diff --git a/BootstrapAdmin.sln b/BootstrapAdmin.sln
index 5a0e0e22..7535726a 100644
--- a/BootstrapAdmin.sln
+++ b/BootstrapAdmin.sln
@@ -155,6 +155,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapClient.Web.Shared"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapClient.Web", "src\blazor\client\BootstrapClient.Web\BootstrapClient.Web.csproj", "{6CD7A35B-93A8-4DB2-B078-EE5A81F40032}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootStarpAdmin.DataAccess.FreeSql", "src\blazor\admin\BootStarpAdmin.DataAccess.FreeSql\BootStarpAdmin.DataAccess.FreeSql.csproj", "{11122D97-B349-4A3E-B7DD-73B8B363C47C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -221,6 +223,10 @@ Global
{6CD7A35B-93A8-4DB2-B078-EE5A81F40032}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CD7A35B-93A8-4DB2-B078-EE5A81F40032}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CD7A35B-93A8-4DB2-B078-EE5A81F40032}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11122D97-B349-4A3E-B7DD-73B8B363C47C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11122D97-B349-4A3E-B7DD-73B8B363C47C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11122D97-B349-4A3E-B7DD-73B8B363C47C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {11122D97-B349-4A3E-B7DD-73B8B363C47C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -258,6 +264,7 @@ Global
{640F598B-6586-4AD6-B544-78CFF2602DFB} = {55A2459A-6BDE-4493-B2C0-5BE1673E99EE}
{93770088-3463-427B-9CD8-88B8D7945C83} = {55A2459A-6BDE-4493-B2C0-5BE1673E99EE}
{6CD7A35B-93A8-4DB2-B078-EE5A81F40032} = {55A2459A-6BDE-4493-B2C0-5BE1673E99EE}
+ {11122D97-B349-4A3E-B7DD-73B8B363C47C} = {45ADEF9B-C8BD-4224-9E12-F6716E85A22C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC}
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index c7627e53..2f59d8ec 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -11,7 +11,7 @@
https://gitee.com/LongbowEnterprise/BootstrapAdmin.git
git
enable
- $(MSBuildProjectName).xml
+ True
diff --git a/src/blazor/Directory.Build.props b/src/blazor/Directory.Build.props
index 56fe008d..a31bd5a5 100644
--- a/src/blazor/Directory.Build.props
+++ b/src/blazor/Directory.Build.props
@@ -1,6 +1,6 @@
-
+
net6.0
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/BootStarpAdmin.DataAccess.FreeSql.csproj b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/BootStarpAdmin.DataAccess.FreeSql.csproj
new file mode 100644
index 00000000..be7b50ac
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/BootStarpAdmin.DataAccess.FreeSql.csproj
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/FilterExtensions.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/FilterExtensions.cs
new file mode 100644
index 00000000..479e398c
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/FilterExtensions.cs
@@ -0,0 +1,63 @@
+using BootstrapBlazor.Components;
+using FreeSql;
+using FreeSql.Internal.Model;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Extensions;
+
+///
+///
+///
+static class FilterExtensions
+{
+ public static ISelect PageIf(this ISelect source, int pageIndex, int pageItems, bool isPage) => isPage
+ ? source.Page(pageIndex, pageItems)
+ : source;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static DynamicFilterInfo ToDynamicFilter(this IEnumerable filters)
+ {
+ var ret = new DynamicFilterInfo() { Filters = new List() };
+
+ // 处理 过滤 高级搜索 自定义搜索
+ foreach (var filter in filters)
+ {
+ var item = new DynamicFilterInfo() { Filters = new List() };
+ var actions = filter.GetFilterConditions();
+ foreach (var f in actions)
+ {
+ item.Logic = f.FilterLogic.ToDynamicFilterLogic();
+ item.Filters.Add(new DynamicFilterInfo()
+ {
+ Field = f.FieldKey,
+ Value = f.FieldValue,
+ Operator = f.FilterAction.ToDynamicFilterOperator()
+ });
+ }
+ ret.Filters.Add(item);
+ }
+ return ret;
+ }
+
+ private static DynamicFilterLogic ToDynamicFilterLogic(this FilterLogic logic) => logic switch
+ {
+ FilterLogic.And => DynamicFilterLogic.And,
+ _ => DynamicFilterLogic.Or
+ };
+
+ private static DynamicFilterOperator ToDynamicFilterOperator(this FilterAction action) => action switch
+ {
+ FilterAction.Equal => DynamicFilterOperator.Equal,
+ FilterAction.NotEqual => DynamicFilterOperator.NotEqual,
+ FilterAction.Contains => DynamicFilterOperator.Contains,
+ FilterAction.NotContains => DynamicFilterOperator.NotContains,
+ FilterAction.GreaterThan => DynamicFilterOperator.GreaterThan,
+ FilterAction.GreaterThanOrEqual => DynamicFilterOperator.GreaterThanOrEqual,
+ FilterAction.LessThan => DynamicFilterOperator.LessThan,
+ FilterAction.LessThanOrEqual => DynamicFilterOperator.LessThanOrEqual,
+ _ => throw new System.NotSupportedException()
+ };
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/FreeSqlExtensions.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/FreeSqlExtensions.cs
new file mode 100644
index 00000000..155472e4
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/FreeSqlExtensions.cs
@@ -0,0 +1,56 @@
+using BootStarpAdmin.DataAccess.FreeSql.Models;
+using BootstrapAdmin.DataAccess.Models;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Extensions;
+
+static class FreeSqlExtensions
+{
+ public static void Mapper(this IFreeSql freeSql)
+ {
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("Navigations");
+ i.Property(n => n.HasChildren).IsIgnore(true);
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("Users");
+ i.Property(n => n.NewPassword).IsIgnore(true);
+ i.Property(n => n.ConfirmPassword).IsIgnore(true);
+ i.Property(n => n.Period).IsIgnore(true);
+ i.Property(n => n.IsReset).IsIgnore(true);
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("Groups");
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("Roles");
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("Exceptions");
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("UserRole");
+ i.Property(s => s.ID).IsIgnore(true);
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("NavigationRole");
+ i.Property(s => s.ID).IsIgnore(true);
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("UserGroup");
+ i.Property(s => s.ID).IsIgnore(true);
+ });
+ freeSql.CodeFirst.ConfigEntity(i =>
+ {
+ i.Name("RoleGroup");
+ i.Property(s => s.ID).IsIgnore(true);
+ });
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/ServicesExtensions.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/ServicesExtensions.cs
new file mode 100644
index 00000000..92f63853
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Extensions/ServicesExtensions.cs
@@ -0,0 +1,46 @@
+using BootStarpAdmin.DataAccess.FreeSql.Extensions;
+using BootStarpAdmin.DataAccess.FreeSql.Service;
+using BootstrapAdmin.Web.Core;
+using BootstrapBlazor.Components;
+using FreeSql;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Microsoft.Extensions.DependencyInjection;
+
+///
+/// FreeSql ORM 注入服务扩展类
+///
+public static class ServicesExtensions
+{
+ ///
+ /// 注入 FreeSql 数据服务类
+ ///
+ ///
+ ///
+ ///
+ public static IServiceCollection AddFreeSql(this IServiceCollection services, Action freeSqlBuilder)
+ {
+ services.TryAddSingleton(provider =>
+ {
+ var builder = new FreeSqlBuilder();
+ freeSqlBuilder(provider, builder);
+ var instance = builder.Build();
+ instance.Mapper();
+ return instance;
+ });
+
+ // 增加数据服务
+ services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
+
+ // 增加业务服务
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ return services;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/NavigationRole.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/NavigationRole.cs
new file mode 100644
index 00000000..742c427a
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/NavigationRole.cs
@@ -0,0 +1,10 @@
+namespace BootStarpAdmin.DataAccess.FreeSql.Models;
+
+class NavigationRole
+{
+ public string? ID { get; set; }
+
+ public string? NavigationID { get; set; }
+
+ public string? RoleID { get; set; }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/RoleApp.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/RoleApp.cs
new file mode 100644
index 00000000..3bf00598
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/RoleApp.cs
@@ -0,0 +1,8 @@
+namespace BootStarpAdmin.DataAccess.FreeSql.Models;
+
+class RoleApp
+{
+ public string? RoleID { get; set; }
+
+ public string? AppID { get; set; }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/RoleGroup.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/RoleGroup.cs
new file mode 100644
index 00000000..7e8b1656
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/RoleGroup.cs
@@ -0,0 +1,10 @@
+namespace BootStarpAdmin.DataAccess.FreeSql.Models;
+
+class RoleGroup
+{
+ public string? ID { get; set; }
+
+ public string? RoleID { get; set; }
+
+ public string? GroupID { get; set; }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/UserGroup.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/UserGroup.cs
new file mode 100644
index 00000000..0ecca85d
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/UserGroup.cs
@@ -0,0 +1,10 @@
+namespace BootStarpAdmin.DataAccess.FreeSql.Models;
+
+class UserGroup
+{
+ public string? ID { get; set; }
+
+ public string? UserID { get; set; }
+
+ public string? GroupID { get; set; }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/UserRole.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/UserRole.cs
new file mode 100644
index 00000000..0af7548c
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Models/UserRole.cs
@@ -0,0 +1,10 @@
+namespace BootStarpAdmin.DataAccess.FreeSql.Models;
+
+class UserRole
+{
+ public string? ID { get; set; }
+
+ public string? UserID { get; set; }
+
+ public string? RoleID { get; set; }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/AppService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/AppService.cs
new file mode 100644
index 00000000..53230213
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/AppService.cs
@@ -0,0 +1,32 @@
+using BootStarpAdmin.DataAccess.FreeSql.Models;
+using BootstrapAdmin.Web.Core;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class AppService : IApp
+{
+ private IFreeSql FreeSql { get; }
+
+ public AppService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ public List GetAppsByRoleId(string? roleId) => FreeSql.Ado.Query("select AppID from RoleApp where RoleID = @roleId", new { roleId });
+
+ public bool SaveAppsByRoleId(string? roleId, IEnumerable appIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from RoleApp where RoleID = @roleId", new { roleId });
+ FreeSql.Insert(appIds.Select(g => new RoleApp { AppID = g, RoleID = roleId })).ExecuteAffrows();
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/DefaultDataService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/DefaultDataService.cs
new file mode 100644
index 00000000..c44cd05d
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/DefaultDataService.cs
@@ -0,0 +1,64 @@
+using BootStarpAdmin.DataAccess.FreeSql.Extensions;
+using BootstrapBlazor.Components;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class DefaultDataService : DataServiceBase where TModel : class, new()
+{
+ private IFreeSql FreeSql { get; }
+
+ public DefaultDataService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ ///
+ /// 删除方法
+ ///
+ ///
+ ///
+ public override async Task DeleteAsync(IEnumerable models)
+ {
+ await FreeSql.Delete(models).ExecuteAffrowsAsync();
+ return true;
+ }
+
+ ///
+ /// 保存方法
+ ///
+ ///
+ ///
+ ///
+ public override async Task SaveAsync(TModel model, ItemChangedType changedType)
+ {
+ if (changedType == ItemChangedType.Add)
+ {
+ await FreeSql.Insert(model).ExecuteAffrowsAsync();
+ }
+ else if (changedType == ItemChangedType.Update)
+ {
+ await FreeSql.Update(model).ExecuteAffrowsAsync();
+ }
+ return true;
+ }
+
+ public override Task> QueryAsync(QueryPageOptions option)
+ {
+ var ret = new QueryData()
+ {
+ IsSorted = true,
+ IsFiltered = true,
+ IsSearch = true,
+ IsAdvanceSearch = option.AdvanceSearchs.Any() || option.CustomerSearchs.Any()
+ };
+ ret.Items = FreeSql.Select()
+ .WhereDynamicFilter(option.Searchs.ToDynamicFilter())
+ .WhereDynamicFilter(option.Filters
+ .Concat(option.AdvanceSearchs)
+ .Concat(option.CustomerSearchs)
+ .ToDynamicFilter())
+ .OrderByPropertyNameIf(option.SortOrder != SortOrder.Unset, option.SortName, option.SortOrder == SortOrder.Asc)
+ .Count(out var count)
+ .PageIf(option.PageIndex, option.PageItems, option.IsPage)
+ .ToList();
+ ret.TotalCount = Convert.ToInt32(count);
+ return Task.FromResult(ret);
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/DictService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/DictService.cs
new file mode 100644
index 00000000..a55111ba
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/DictService.cs
@@ -0,0 +1,156 @@
+using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.Web.Core;
+using Longbow.Security.Cryptography;
+using Microsoft.Extensions.Configuration;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class DictService : IDict
+{
+ private IFreeSql FreeSql { get; }
+
+ private string? AppId { get; set; }
+
+ public DictService(IFreeSql freeSql, IConfiguration configuration)
+ {
+ FreeSql = freeSql;
+ AppId = configuration.GetValue("AppId", "BA");
+ }
+
+ public bool AuthenticateDemo(string code)
+ {
+ var ret = false;
+ if (!string.IsNullOrEmpty(code))
+ {
+ var dicts = GetAll();
+ var salt = dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "授权盐值" && d.Define == EnumDictDefine.System)?.Code;
+ var authCode = dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "哈希结果" && d.Define == EnumDictDefine.System)?.Code;
+ if (!string.IsNullOrEmpty(salt))
+ {
+ ret = LgbCryptography.ComputeHash(code, salt) == authCode;
+ }
+ }
+ return ret;
+ }
+
+ public List GetAll()
+ {
+ return FreeSql.Select().ToList();
+ }
+
+ public Dictionary GetApps()
+ {
+ var dicts = GetAll();
+
+ return dicts.Where(d => d.Category == "应用程序").Select(s => new KeyValuePair(s.Code, s.Name)).ToDictionary(i => i.Key, i => i.Value);
+ }
+
+ public int GetCookieExpiresPeriod()
+ {
+ var dicts = GetAll();
+ var code = dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "Cookie保留时长" && d.Define == EnumDictDefine.System)?.Code ?? "0";
+ _ = int.TryParse(code, out var ret);
+ return ret;
+ }
+
+ public string GetCurrentLogin()
+ {
+ var dicts = GetAll();
+ return dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "登录界面" && d.Define == EnumDictDefine.System)?.Code ?? "Login";
+ }
+
+ public Dictionary GetLogins()
+ {
+ var dicts = GetAll();
+ return dicts.Where(d => d.Category == "系统首页").Select(d => new KeyValuePair(d.Code, d.Name)).OrderBy(i => i.Value).ToDictionary(i => i.Key, i => i.Value);
+ }
+
+ public string? GetNotificationUrl(string appId) => GetUrlByName(appId, "系统通知地址");
+
+ public string? GetProfileUrl(string appId) => GetUrlByName(appId, "个人中心地址");
+
+ public string? GetSettingsUrl(string appId) => GetUrlByName(appId, "系统设置地址");
+
+ public Dictionary GetThemes()
+ {
+ var dicts = GetAll();
+ return dicts.Where(d => d.Category == "网站样式").Select(d => new KeyValuePair(d.Code, d.Name)).ToDictionary(i => i.Key, i => i.Value);
+ }
+
+ public string GetWebFooter()
+ {
+ var dicts = GetAll();
+ var title = "网站页脚";
+ var name = dicts.FirstOrDefault(d => d.Category == "应用程序" && d.Code == AppId)?.Name;
+ if (!string.IsNullOrEmpty(name))
+ {
+ var dict = dicts.FirstOrDefault(d => d.Category == name && d.Name == "网站页脚") ?? dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "网站页脚");
+ title = dict?.Code ?? "网站标题";
+ }
+ return title;
+ }
+
+ public string GetWebTitle()
+ {
+ var dicts = GetAll();
+ var title = "网站标题";
+ var name = dicts.FirstOrDefault(d => d.Category == "应用程序" && d.Code == AppId)?.Name;
+ if (!string.IsNullOrEmpty(name))
+ {
+ var dict = dicts.FirstOrDefault(d => d.Category == name && d.Name == "网站标题") ?? dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "网站标题");
+ title = dict?.Code ?? "网站标题";
+ }
+ return title;
+ }
+
+ public bool IsDemo()
+ {
+ var dicts = GetAll();
+ var code = dicts.FirstOrDefault(d => d.Category == "网站设置" && d.Name == "演示系统" && d.Define == EnumDictDefine.System)?.Code ?? "0";
+ return code == "1";
+ }
+
+ public string RetrieveIconFolderPath()
+ {
+ var dicts = GetAll();
+ return dicts.FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == EnumDictDefine.System)?.Code ?? "images/uploder/";
+ }
+
+ private bool SaveDict(Dict dict) => FreeSql.Update().Where(s => s.Category == dict.Category && s.Name == dict.Code).Set(s => s.Code, dict.Code).ExecuteAffrows() > 0;
+
+ public bool SaveCookieExpiresPeriod(int expiresPeriod) => SaveDict(new Dict { Category = "网站设置", Name = "Cookie保留时长", Code = expiresPeriod.ToString() });
+
+ public bool SaveDemo(bool isDemo)
+ {
+ return FreeSql.Update()
+ .Where(s => s.Category == "网站设置" && s.Name == "演示系统" && s.Define == EnumDictDefine.System)
+ .Set(s => s.Code, isDemo ? "1" : "0").ExecuteAffrows() > 0;
+ }
+
+ public bool SaveHealthCheck(bool enable = true)
+ {
+ return FreeSql.Update()
+ .Where(s => s.Category == "网站设置" && s.Name == "健康检查" && s.Define == EnumDictDefine.System)
+ .Set(s => s.Code, enable ? "1" : "0").ExecuteAffrows() > 0;
+ }
+
+ public bool SaveLogin(string login) => SaveDict(new Dict { Category = "网站设置", Name = "登录界面", Code = login });
+
+ public bool SaveTheme(string theme) => SaveDict(new Dict { Category = "网站设置", Name = "使用样式", Code = theme });
+
+ public bool SaveWebFooter(string footer) => SaveDict(new Dict { Category = "网站设置", Name = "网站页脚", Code = footer });
+
+ public bool SaveWebTitle(string title) => SaveDict(new Dict { Category = "网站设置", Name = "网站标题", Code = title });
+
+ private string? GetUrlByName(string appId, string dictName)
+ {
+ string? url = null;
+ var dicts = GetAll();
+ var appName = dicts.FirstOrDefault(d => d.Category == "应用程序" && d.Code == appId && d.Define == EnumDictDefine.System)?.Name;
+ if (!string.IsNullOrEmpty(appName))
+ {
+ url = dicts.FirstOrDefault(d => d.Category == appName && d.Name == dictName && d.Define == EnumDictDefine.Customer)?.Code;
+ }
+ return url;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/ExceptionService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/ExceptionService.cs
new file mode 100644
index 00000000..4de4efc3
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/ExceptionService.cs
@@ -0,0 +1,60 @@
+using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.Web.Core;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class ExceptionService : IException
+{
+ private IFreeSql FreeSql { get; }
+
+ public ExceptionService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ public (IEnumerable Items, int ItemsCount) GetAll(string? searchText, ExceptionFilter filter, int pageIndex, int pageItems, List sortList)
+ {
+ var items = FreeSql.Select();
+
+ if (!string.IsNullOrEmpty(searchText))
+ {
+ items.Where($"ErrorPage Like %@searchText% or Message Like %@searchText% or StackTrace Like %@searchText%", new { searchText });
+ }
+
+ if (!string.IsNullOrEmpty(filter.Category))
+ {
+ items.Where("Category = @Category", new { filter.Category });
+ }
+
+ if (!string.IsNullOrEmpty(filter.UserId))
+ {
+ items.Where("UserId Like %@UserId%", new { filter.UserId });
+ }
+
+ if (!string.IsNullOrEmpty(filter.ErrorPage))
+ {
+ items.Where("ErrorPage Like %{ErrorPage}%", new { filter.ErrorPage });
+ }
+
+ items.Where("LogTime >= @Star and LogTime <= @End", new { filter.Star, filter.End });
+
+ if (sortList.Any())
+ {
+ items.OrderBy(string.Join(", ", sortList));
+ }
+ else
+ {
+ items.OrderBy("UserId, ErrorPage, Logtime desc");
+ }
+ var errors = items.Count(out var count).Page(pageIndex, pageItems).ToList();
+
+ return (errors, Convert.ToInt32(count));
+ }
+
+ public bool Log(Error exception)
+ {
+ try
+ {
+ FreeSql.Insert(exception).ExecuteAffrows();
+ }
+ catch { }
+ return true;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/GroupService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/GroupService.cs
new file mode 100644
index 00000000..a5f4944f
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/GroupService.cs
@@ -0,0 +1,56 @@
+using BootStarpAdmin.DataAccess.FreeSql.Models;
+using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.Web.Core;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class GroupService : IGroup
+{
+ private IFreeSql FreeSql { get; }
+
+ public GroupService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ public List GetAll() => FreeSql.Select().ToList();
+
+ public List GetGroupsByRoleId(string? roleId) => FreeSql.Ado.Query("select GroupID from RoleGroup where RoleID = @roleId", new { roleId });
+
+ public List GetGroupsByUserId(string? userId) => FreeSql.Ado.Query("select GroupID from UserGroup where UserID = @userId", new { userId });
+
+ public bool SaveGroupsByRoleId(string? roleId, IEnumerable groupIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from RoleGroup where RoleID = @roleId", new { roleId });
+ FreeSql.Insert(groupIds.Select(g => new RoleGroup { GroupID = g, RoleID = roleId })).ExecuteAffrows();
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+
+ public bool SaveGroupsByUserId(string? userId, IEnumerable groupIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from UserGroup where UserID = @userId", new { userId });
+ FreeSql.Insert(groupIds.Select(g => new UserGroup { GroupID = g, UserID = userId }));
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/LoginService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/LoginService.cs
new file mode 100644
index 00000000..fef7f4b0
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/LoginService.cs
@@ -0,0 +1,11 @@
+using BootstrapAdmin.Web.Core;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class LoginService : ILogin
+{
+ public Task Log(string userName, bool result)
+ {
+ return Task.FromResult(true);
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/NavigationService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/NavigationService.cs
new file mode 100644
index 00000000..e824b54c
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/NavigationService.cs
@@ -0,0 +1,38 @@
+using BootStarpAdmin.DataAccess.FreeSql.Models;
+using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.Web.Core;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class NavigationService : INavigation
+{
+ private IFreeSql FreeSql { get; }
+
+ public NavigationService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ public List GetAllMenus(string userName)
+ {
+ return FreeSql.Ado.Query($"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 = @Define 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", Define = EnumDictDefine.System });
+ }
+
+ public List GetMenusByRoleId(string? roleId) => FreeSql.Ado.Query("select NavigationID from NavigationRole where RoleID = @roleId", new { roleId });
+
+ public bool SaveMenusByRoleId(string? roleId, List menuIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from NavigationRole where RoleID = @roleId", new { roleId });
+ FreeSql.Insert(menuIds.Select(g => new NavigationRole { NavigationID = g, RoleID = roleId })).ExecuteAffrows();
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/RoleService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/RoleService.cs
new file mode 100644
index 00000000..36a014ce
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/RoleService.cs
@@ -0,0 +1,80 @@
+using BootStarpAdmin.DataAccess.FreeSql.Models;
+using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.Web.Core;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class RoleService : IRole
+{
+ private IFreeSql FreeSql { get; }
+
+ public RoleService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ public List GetAll()
+ {
+ return FreeSql.Select().ToList();
+ }
+
+ public List GetRolesByGroupId(string? groupId) => FreeSql.Ado.Query("select RoleID from RoleGroup where GroupID = @groupId", new { groupId });
+
+ public List GetRolesByMenuId(string? menuId) => FreeSql.Ado.Query("select RoleID from NavigationRole where NavigationID = @menuId", new { menuId });
+
+ public List GetRolesByUserId(string? userId) => FreeSql.Ado.Query("select RoleID from UserRole where UserID = @userId", new { userId });
+
+ public bool SaveRolesByGroupId(string? groupId, IEnumerable roleIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from RoleGroup where GroupID = @groupId", new { groupId });
+ FreeSql.Insert(roleIds.Select(g => new RoleGroup { RoleID = g, GroupID = groupId })).ExecuteAffrows();
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+
+ public bool SaveRolesByMenuId(string? menuId, IEnumerable roleIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from NavigationRole where NavigationID = @menuId", new { menuId });
+ FreeSql.Insert(roleIds.Select(g => new NavigationRole { RoleID = g, NavigationID = menuId })).ExecuteAffrows();
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+
+ public bool SaveRolesByUserId(string? userId, IEnumerable roleIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from UserRole where UserID = @userId", new { userId });
+ FreeSql.Insert(roleIds.Select(g => new UserRole { RoleID = g, UserID = userId })).ExecuteAffrows();
+ });
+ ret = true;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+}
diff --git a/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/UserService.cs b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/UserService.cs
new file mode 100644
index 00000000..3c6bc4fa
--- /dev/null
+++ b/src/blazor/admin/BootStarpAdmin.DataAccess.FreeSql/Service/UserService.cs
@@ -0,0 +1,194 @@
+using BootStarpAdmin.DataAccess.FreeSql.Models;
+using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.Web.Core;
+using Longbow.Security.Cryptography;
+
+namespace BootStarpAdmin.DataAccess.FreeSql.Service;
+
+class UserService : IUser
+{
+ private IFreeSql FreeSql { get; }
+
+ public UserService(IFreeSql freeSql) => FreeSql = freeSql;
+
+ public bool Authenticate(string userName, string password)
+ {
+ var user = FreeSql.Select().Where(s => s.ApprovedTime != null && s.UserName == userName).ToOne(s => new User
+ {
+ DisplayName = s.DisplayName,
+ PassSalt = s.PassSalt,
+ Password = s.Password
+ });
+
+ var isAuth = false;
+ if (user != null && !string.IsNullOrEmpty(user.PassSalt))
+ {
+ isAuth = user.Password == LgbCryptography.ComputeHash(password, user.PassSalt);
+ }
+ return isAuth;
+ }
+
+ public List GetAll()
+ {
+ return FreeSql.Select().ToList();
+ }
+
+ public List GetApps(string userName)
+ {
+ return FreeSql.Ado.Query($"select d.Code from Dicts d inner join RoleApp ra on d.Code = ra.AppId inner join (select r.Id from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @UserName union select r.Id from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join Groups g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @UserName) r on ra.RoleId = r.ID union select Code from Dicts where Category = @Category and exists(select r.ID from Roles r inner join UserRole ur on r.ID = ur.RoleID inner join Users u on ur.UserID = u.ID where u.UserName = @UserName and r.RoleName = @RoleName union select r.ID from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join Groups g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID where u.UserName = @UserName and r.RoleName = @RoleName)", new { UserName = userName, Category = "应用程序", RoleName = "Administrators" }).ToList();
+ }
+
+ public string? GetDisplayName(string? userName)
+ {
+ return FreeSql.Select().Where(s => s.UserName == userName).ToOne(s => s.DisplayName);
+ }
+
+ public List GetRoles(string userName)
+ {
+ return FreeSql.Ado.Query($"select r.RoleName from Roles r inner join UserRole ur on r.ID=ur.RoleID inner join Users u on ur.UserID = u.ID and u.UserName = @userName union select r.RoleName from Roles r inner join RoleGroup rg on r.ID = rg.RoleID inner join Groups g on rg.GroupID = g.ID inner join UserGroup ug on ug.GroupID = g.ID inner join Users u on ug.UserID = u.ID and u.UserName = @userName", new { userName }).ToList();
+ }
+
+ public User? GetUserByUserName(string? userName) => string.IsNullOrEmpty(userName) ? null : FreeSql.Select().Where(i => i.UserName == userName).ToOne();
+
+ public List GetUsersByGroupId(string? groupId)
+ {
+ return FreeSql.Ado.Query("select UserID from UserGroup where GroupID = @groupId", new { groupId }).ToList();
+ }
+
+ public List GetUsersByRoleId(string? roleId)
+ {
+ return FreeSql.Ado.Query("select UserID from UserRole where RoleID = @roleId", new { roleId }).ToList();
+ }
+
+ public bool SaveUser(string userName, string displayName, string password)
+ {
+ var salt = LgbCryptography.GenerateSalt();
+ var pwd = LgbCryptography.ComputeHash(password, salt);
+ var user = FreeSql.Select().Where(s => s.UserName == userName).ToOne();
+ bool ret = default;
+ if (user == null)
+ {
+ // 开始事务
+ FreeSql.Transaction(() =>
+ {
+ user = new User()
+ {
+ Id = "0",
+ ApprovedBy = "System",
+ ApprovedTime = DateTime.Now,
+ DisplayName = "手机用户",
+ UserName = userName,
+ Icon = "default.jpg",
+ Description = "系统默认创建",
+ PassSalt = salt,
+ Password = pwd
+ };
+ FreeSql.Insert(user).ExecuteAffrows();
+ // 授权 Default 角色
+ FreeSql.Ado.ExecuteNonQuery("insert into UserRole (UserID, RoleID) select ID, (select ID from Roles where RoleName = 'Default') RoleId from Users where UserName = @userName", new { userName });
+ ret = true;
+ });
+ }
+ else
+ {
+ user.DisplayName = displayName;
+ user.PassSalt = salt;
+ user.Password = pwd;
+ FreeSql.Update(user);
+ ret = true;
+ }
+ return ret;
+ }
+
+ public bool SaveUsersByGroupId(string? groupId, IEnumerable userIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from UserGroup where GroupId = @groupId", new { groupId });
+ FreeSql.Insert(userIds.Select(g => new UserGroup { UserID = g, GroupID = groupId })).ExecuteAffrows();
+ });
+
+ ret = true;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+
+ public bool SaveUsersByRoleId(string? roleId, IEnumerable userIds)
+ {
+ var ret = false;
+ try
+ {
+ FreeSql.Transaction(() =>
+ {
+ FreeSql.Ado.ExecuteNonQuery("delete from UserRole where RoleID = @roleId", new { roleId });
+ FreeSql.Insert(userIds.Select(g => new UserRole { UserID = g, RoleID = roleId })).ExecuteAffrows();
+ ret = true;
+ });
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool TryCreateUserByPhone(string phone, string code, string appId, ICollection roles)
+ {
+ var ret = false;
+ try
+ {
+ var salt = LgbCryptography.GenerateSalt();
+ var pwd = LgbCryptography.ComputeHash(code, salt);
+ var user = FreeSql.Select().Where(s => s.UserName == phone).ToOne();
+ if (user == null)
+ {
+ FreeSql.Transaction(() =>
+ {
+ user = new User()
+ {
+ ApprovedBy = "Mobile",
+ ApprovedTime = DateTime.Now,
+ DisplayName = "手机用户",
+ UserName = phone,
+ Icon = "default.jpg",
+ Description = "手机用户",
+ PassSalt = salt,
+ Password = LgbCryptography.ComputeHash(code, salt),
+ App = appId
+ };
+ FreeSql.Insert(user).ExecuteAffrows();
+ // Authorization
+ var roleIds = FreeSql.Ado.Query("select ID from Roles where RoleName in (@roles)", new { roles });
+ FreeSql.Insert(roleIds.Select(g => new UserRole { RoleID = g, UserID = user.Id }));
+ });
+ }
+ else
+ {
+ user.PassSalt = salt;
+ user.Password = pwd;
+ FreeSql.Update(user).ExecuteAffrows();
+ }
+ ret = true;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return ret;
+ }
+}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/EntityConfiguration.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/EntityConfiguration.cs
index 8c982669..5d32eb41 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/EntityConfiguration.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/EntityConfiguration.cs
@@ -1,4 +1,5 @@
-using BootstrapAdmin.DataAccess.Models;
+using BootstrapAdmin.DataAccess.EFCore.Models;
+using BootstrapAdmin.DataAccess.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/DictService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/DictService.cs
index e6a9b2d2..ee7c3bd9 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/DictService.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/DictService.cs
@@ -114,4 +114,49 @@ class DictService : IDict
_ = int.TryParse(code, out var ret);
return ret;
}
+
+ public string GetCurrentLogin()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool SaveLogin(string login)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool SaveTheme(string theme)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool SaveWebTitle(string title)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool SaveWebFooter(string footer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool SaveCookieExpiresPeriod(int expiresPeriod)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string? GetProfileUrl(string appId)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string? GetSettingsUrl(string appId)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string? GetNotificationUrl(string appId)
+ {
+ throw new NotImplementedException();
+ }
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/UserService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/UserService.cs
index 70640858..c2351009 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/UserService.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.EFCore/Services/UserService.cs
@@ -136,4 +136,14 @@ public class UserService : IUser
}
return ret;
}
+
+ List IUser.GetAll()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryCreateUserByPhone(string phone, string code, string appId, ICollection roles)
+ {
+ throw new NotImplementedException();
+ }
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/AppInfo.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/AppInfo.cs
index 3fba33e9..99e7b4f0 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/AppInfo.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/AppInfo.cs
@@ -2,6 +2,9 @@
namespace BootstrapAdmin.DataAccess.Models;
+///
+///
+///
public class AppInfo
{
///
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/DBLog.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/DBLog.cs
index c410bf13..6b3fb959 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/DBLog.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/DBLog.cs
@@ -1,33 +1,32 @@
using System.ComponentModel;
-namespace BootstrapAdmin.DataAccess.Models
+namespace BootstrapAdmin.DataAccess.Models;
+
+///
+/// 后台数据库脚本执行日志实体类
+///
+public class DBLog
{
///
- /// 后台数据库脚本执行日志实体类
+ /// 获得/设置 主键ID
///
- public class DBLog
- {
- ///
- /// 获得/设置 主键ID
- ///
- public string? Id { get; set; }
+ public string? Id { get; set; }
- ///
- /// 获得/设置 当前登陆名
- ///
- [DisplayName("所属用户")]
- public string? UserName { get; set; }
+ ///
+ /// 获得/设置 当前登陆名
+ ///
+ [DisplayName("所属用户")]
+ public string? UserName { get; set; }
- ///
- /// 获得/设置 数据库执行脚本
- ///
- [DisplayName("脚本内容")]
- public string SQL { get; set; } = "";
+ ///
+ /// 获得/设置 数据库执行脚本
+ ///
+ [DisplayName("脚本内容")]
+ public string SQL { get; set; } = "";
- ///
- /// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联
- ///
- [DisplayName("执行时间")]
- public DateTime LogTime { get; set; }
- }
+ ///
+ /// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联
+ ///
+ [DisplayName("执行时间")]
+ public DateTime LogTime { get; set; }
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Dict.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Dict.cs
index e537d620..c0ac991f 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Dict.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Dict.cs
@@ -1,12 +1,14 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
namespace BootstrapAdmin.DataAccess.Models;
///
/// 字典配置项
///
+[Table("Dicts")]
public class Dict
{
///
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Error.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Error.cs
index d485569f..bcde4437 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Error.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Error.cs
@@ -12,6 +12,9 @@ public class Error
///
public string? Id { get; set; }
+ ///
+ ///
+ ///
[DisplayName("应用程序")]
public string? AppDomainName { get; set; }
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Group.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Group.cs
index b425f218..ba4a8401 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Group.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Group.cs
@@ -1,37 +1,40 @@
using System.ComponentModel.DataAnnotations;
-namespace BootstrapAdmin.DataAccess.Models
+namespace BootstrapAdmin.DataAccess.Models;
+
+///
+/// Group 实体类
+///
+public class Group
{
///
- /// Group 实体类
+ /// 获得/设置 主键 ID
///
- public class Group
- {
- ///
- /// 获得/设置 主键 ID
- ///
- public string? Id { get; set; }
+ public string? Id { get; set; }
- ///
- /// 获得/设置 群组名称
- ///
- [Display(Name = "群组名称")]
- [NotNull]
- public string? GroupName { get; set; }
+ ///
+ /// 获得/设置 群组名称
+ ///
+ [Display(Name = "群组名称")]
+ [NotNull]
+ public string? GroupName { get; set; }
- ///
- /// 获得/设置 群组编码
- ///
- [Display(Name = "群组编码")]
- [NotNull]
- public string? GroupCode { get; set; }
+ ///
+ /// 获得/设置 群组编码
+ ///
+ [Display(Name = "群组编码")]
+ [NotNull]
+ public string? GroupCode { get; set; }
- ///
- /// 获得/设置 群组描述
- ///
- [Display(Name = "群组描述")]
- public string? Description { get; set; }
+ ///
+ /// 获得/设置 群组描述
+ ///
+ [Display(Name = "群组描述")]
+ public string? Description { get; set; }
- public override string ToString() => $"{GroupName} ({GroupCode})";
- }
+ ///
+ ///
+ ///
+ ///
+ public override string ToString() => $"{GroupName} ({GroupCode})";
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Navigation.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Navigation.cs
index a9d9c4f6..846dfcfd 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Navigation.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Navigation.cs
@@ -1,78 +1,79 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
-namespace BootstrapAdmin.DataAccess.Models
+namespace BootstrapAdmin.DataAccess.Models;
+
+///
+/// Bootstrap Admin 后台管理菜单相关操作实体类
+///
+[Table("Navigations")]
+public class Navigation
{
///
- /// Bootstrap Admin 后台管理菜单相关操作实体类
+ /// 获得/设置 菜单主键ID
///
- public class Navigation
- {
- ///
- /// 获得/设置 菜单主键ID
- ///
- [NotNull]
- public string? Id { set; get; }
+ [NotNull]
+ public string? Id { set; get; }
- ///
- /// 获得/设置 父级菜单ID 默认为 0
- ///
- public string ParentId { set; get; } = "0";
+ ///
+ /// 获得/设置 父级菜单ID 默认为 0
+ ///
+ public string ParentId { set; get; } = "0";
- ///
- /// 获得/设置 菜单名称
- ///
- [Display(Name = "名称")]
- [NotNull]
- public string? Name { get; set; }
+ ///
+ /// 获得/设置 菜单名称
+ ///
+ [Display(Name = "名称")]
+ [NotNull]
+ public string? Name { get; set; }
- ///
- /// 获得/设置 菜单序号
- ///
- [Display(Name = "序号")]
- public int Order { get; set; }
+ ///
+ /// 获得/设置 菜单序号
+ ///
+ [Display(Name = "序号")]
+ public int Order { get; set; }
- ///
- /// 获得/设置 菜单图标
- ///
- [Display(Name = "图标")]
- public string? Icon { get; set; }
+ ///
+ /// 获得/设置 菜单图标
+ ///
+ [Display(Name = "图标")]
+ public string? Icon { get; set; }
- ///
- /// 获得/设置 菜单URL地址
- ///
- [NotNull]
- [Display(Name = "地址")]
- public string? Url { get; set; }
+ ///
+ /// 获得/设置 菜单URL地址
+ ///
+ [NotNull]
+ [Display(Name = "地址")]
+ public string? Url { get; set; }
- ///
- /// 获得/设置 菜单分类, 0 表示系统菜单 1 表示用户自定义菜单
- ///
- [Display(Name = "类别")]
- public EnumNavigationCategory Category { get; set; }
+ ///
+ /// 获得/设置 菜单分类, 0 表示系统菜单 1 表示用户自定义菜单
+ ///
+ [Display(Name = "类别")]
+ public EnumNavigationCategory Category { get; set; }
- ///
- /// 获得/设置 链接目标
- ///
- [Display(Name = "目标")]
- public string? Target { get; set; }
+ ///
+ /// 获得/设置 链接目标
+ ///
+ [Display(Name = "目标")]
+ public string? Target { get; set; }
- ///
- /// 获得/设置 是否为资源文件, 0 表示菜单 1 表示资源 2 表示按钮
- ///
- [Display(Name = "类型")]
- public EnumResource IsResource { get; set; }
+ ///
+ /// 获得/设置 是否为资源文件, 0 表示菜单 1 表示资源 2 表示按钮
+ ///
+ [Display(Name = "类型")]
+ public EnumResource IsResource { get; set; }
- ///
- /// 获得/设置 所属应用程序,此属性由BA后台字典表分配
- ///
- [Display(Name = "所属应用")]
- public string? Application { get; set; }
+ ///
+ /// 获得/设置 所属应用程序,此属性由BA后台字典表分配
+ ///
+ [Display(Name = "所属应用")]
+ public string? Application { get; set; }
- ///
- ///
- ///
- public bool HasChildren { get; set; }
- }
+ ///
+ ///
+ ///
+ public bool HasChildren { get; set; }
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Role.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Role.cs
index 7a262c5a..ce6b65f6 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Role.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/Role.cs
@@ -1,30 +1,29 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
-namespace BootstrapAdmin.DataAccess.Models
+namespace BootstrapAdmin.DataAccess.Models;
+
+///
+/// Role 实体类
+///
+public class Role
{
///
- /// Role 实体类
+ /// 获得/设置 角色主键ID
///
- public class Role
- {
- ///
- /// 获得/设置 角色主键ID
- ///
- public string? Id { get; set; }
+ public string? Id { get; set; }
- ///
- /// 获得/设置 角色名称
- ///
- [DisplayName("角色名称")]
- [NotNull]
- public string? RoleName { get; set; }
+ ///
+ /// 获得/设置 角色名称
+ ///
+ [DisplayName("角色名称")]
+ [NotNull]
+ public string? RoleName { get; set; }
- ///
- /// 获得/设置 角色描述
- ///
- [DisplayName("角色描述")]
- [NotNull]
- public string? Description { get; set; }
- }
+ ///
+ /// 获得/设置 角色描述
+ ///
+ [DisplayName("角色描述")]
+ [NotNull]
+ public string? Description { get; set; }
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs
index 81dc3e76..f82d78d0 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.Models/User.cs
@@ -1,162 +1,161 @@
using System.ComponentModel.DataAnnotations;
-namespace BootstrapAdmin.DataAccess.Models
+namespace BootstrapAdmin.DataAccess.Models;
+
+///
+///
+///
+public class User
{
///
- ///
+ /// 获得/设置 系统登录用户名
///
- public class User
- {
- ///
- /// 获得/设置 系统登录用户名
- ///
- [Display(Name = "登录名称")]
- [Required(ErrorMessage = "{0}不可为空")]
- [RegularExpression("^[a-zA-Z0-9_@.]*$", ErrorMessage = "登录名称包含非法字符")]
- [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
- [NotNull]
- public string? UserName { get; set; }
-
- ///
- /// 获得/设置 用户显示名称
- ///
- [Display(Name = "显示名称")]
- [Required(ErrorMessage = "{0}不可为空")]
- [MaxLength(20, ErrorMessage = "{0}不能超过 20 个字符")]
- [NotNull]
- public string? DisplayName { get; set; }
-
- ///
- /// 获得/设置 用户头像图标路径
- ///
- [Display(Name = "用户头像")]
- public string? Icon { get; set; }
-
- ///
- /// 获得/设置 用户设置样式表名称
- ///
- [Display(Name = "主题")]
- public string? Css { get; set; }
-
- ///
- /// 获得/设置 用户默认登陆 App 标识
- ///
- [Display(Name = "默认 APP")]
- public string? App { get; set; }
-
- ///
- /// 获得/设置 用户主键ID
- ///
- public string? Id { get; set; }
-
- ///
- /// 获取/设置 密码
- ///
- [Display(Name = "密码")]
- [Required(ErrorMessage = "{0}不可为空")]
- [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
- [NotNull]
- public string? Password { get; set; }
-
- ///
- /// 获取/设置 密码盐
- ///
- public string? PassSalt { get; set; }
-
- ///
- /// 获得/设置 用户注册时间
- ///
- [Display(Name = "注册时间")]
- public DateTime RegisterTime { get; set; } = DateTime.Now;
-
- ///
- /// 获得/设置 用户被批复时间
- ///
- [Display(Name = "授权时间")]
- public DateTime? ApprovedTime { get; set; }
-
- ///
- /// 获得/设置 用户批复人
- ///
- [Display(Name = "授权人")]
- public string? ApprovedBy { get; set; }
-
- ///
- /// 获得/设置 用户的申请理由
- ///
- [Display(Name = "说明")]
- [NotNull]
- public string? Description { get; set; }
-
- ///
- /// 获得/设置 通知描述 2分钟内为刚刚
- ///
- public string? Period { get; set; }
-
- ///
- /// 获得/设置 新密码
- ///
- [Display(Name = "新密码")]
- [Required(ErrorMessage = "{0}不可为空")]
- [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
- [NotNull]
- public string? NewPassword { get; set; }
-
- ///
- /// 获得/设置 新密码
- ///
- [Display(Name = "确认密码")]
- [Required(ErrorMessage = "{0}不可为空")]
- [Compare("NewPassword", ErrorMessage = "{0}与{1}不一致")]
- [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
- [NotNull]
- public string? ConfirmPassword { get; set; }
-
- ///
- /// 获得/设置 是否重置密码
- ///
- public int IsReset { get; set; }
-
- ///
- /// 获得/设置 默认格式为 DisplayName (UserName)
- ///
- ///
- public override string ToString() => $"{DisplayName} ({UserName})";
- }
+ [Display(Name = "登录名称")]
+ [Required(ErrorMessage = "{0}不可为空")]
+ [RegularExpression("^[a-zA-Z0-9_@.]*$", ErrorMessage = "登录名称包含非法字符")]
+ [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
+ [NotNull]
+ public string? UserName { get; set; }
///
- /// 用户状态枚举类型
+ /// 获得/设置 用户显示名称
///
- public enum UserStates
- {
- ///
- /// 更改密码
- ///
- ChangePassword,
+ [Display(Name = "显示名称")]
+ [Required(ErrorMessage = "{0}不可为空")]
+ [MaxLength(20, ErrorMessage = "{0}不能超过 20 个字符")]
+ [NotNull]
+ public string? DisplayName { get; set; }
- ///
- /// 更改样式
- ///
- ChangeTheme,
+ ///
+ /// 获得/设置 用户头像图标路径
+ ///
+ [Display(Name = "用户头像")]
+ public string? Icon { get; set; }
- ///
- /// 更改显示名称
- ///
- ChangeDisplayName,
+ ///
+ /// 获得/设置 用户设置样式表名称
+ ///
+ [Display(Name = "主题")]
+ public string? Css { get; set; }
- ///
- /// 审批用户
- ///
- ApproveUser,
+ ///
+ /// 获得/设置 用户默认登陆 App 标识
+ ///
+ [Display(Name = "默认 APP")]
+ public string? App { get; set; }
- ///
- /// 拒绝用户
- ///
- RejectUser,
+ ///
+ /// 获得/设置 用户主键ID
+ ///
+ public string? Id { get; set; }
- ///
- /// 保存默认应用
- ///
- SaveApp
- }
+ ///
+ /// 获取/设置 密码
+ ///
+ [Display(Name = "密码")]
+ [Required(ErrorMessage = "{0}不可为空")]
+ [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
+ [NotNull]
+ public string? Password { get; set; }
+
+ ///
+ /// 获取/设置 密码盐
+ ///
+ public string? PassSalt { get; set; }
+
+ ///
+ /// 获得/设置 用户注册时间
+ ///
+ [Display(Name = "注册时间")]
+ public DateTime RegisterTime { get; set; } = DateTime.Now;
+
+ ///
+ /// 获得/设置 用户被批复时间
+ ///
+ [Display(Name = "授权时间")]
+ public DateTime? ApprovedTime { get; set; }
+
+ ///
+ /// 获得/设置 用户批复人
+ ///
+ [Display(Name = "授权人")]
+ public string? ApprovedBy { get; set; }
+
+ ///
+ /// 获得/设置 用户的申请理由
+ ///
+ [Display(Name = "说明")]
+ [NotNull]
+ public string? Description { get; set; }
+
+ ///
+ /// 获得/设置 通知描述 2分钟内为刚刚
+ ///
+ public string? Period { get; set; }
+
+ ///
+ /// 获得/设置 新密码
+ ///
+ [Display(Name = "新密码")]
+ [Required(ErrorMessage = "{0}不可为空")]
+ [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
+ [NotNull]
+ public string? NewPassword { get; set; }
+
+ ///
+ /// 获得/设置 新密码
+ ///
+ [Display(Name = "确认密码")]
+ [Required(ErrorMessage = "{0}不可为空")]
+ [Compare("NewPassword", ErrorMessage = "{0}与{1}不一致")]
+ [MaxLength(16, ErrorMessage = "{0}不能超过 16 个字符")]
+ [NotNull]
+ public string? ConfirmPassword { get; set; }
+
+ ///
+ /// 获得/设置 是否重置密码
+ ///
+ public int IsReset { get; set; }
+
+ ///
+ /// 获得/设置 默认格式为 DisplayName (UserName)
+ ///
+ ///
+ public override string ToString() => $"{DisplayName} ({UserName})";
+}
+
+///
+/// 用户状态枚举类型
+///
+public enum UserStates
+{
+ ///
+ /// 更改密码
+ ///
+ ChangePassword,
+
+ ///
+ /// 更改样式
+ ///
+ ChangeTheme,
+
+ ///
+ /// 更改显示名称
+ ///
+ ChangeDisplayName,
+
+ ///
+ /// 审批用户
+ ///
+ ApproveUser,
+
+ ///
+ /// 拒绝用户
+ ///
+ RejectUser,
+
+ ///
+ /// 保存默认应用
+ ///
+ SaveApp
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Coverters/StringToEnumConverter.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Coverters/StringToEnumConverter.cs
index 680477d6..2b0fb8a1 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Coverters/StringToEnumConverter.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Coverters/StringToEnumConverter.cs
@@ -3,7 +3,7 @@
///
/// 字符串转枚举转换器
///
-public class StringToEnumConverter
+class StringToEnumConverter
{
private Type TargetType { get; set; }
@@ -21,7 +21,10 @@ public class StringToEnumConverter
///
public object? ConvertFromDb(object? value)
{
- if (value == null) throw new ArgumentNullException(nameof(value));
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
object? ret;
if (value != null && Enum.TryParse(TargetType, value.ToString(), true, out var v))
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Extensions/ServicesExtensions.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Extensions/ServicesExtensions.cs
index 944eda27..c91bcade 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Extensions/ServicesExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Extensions/ServicesExtensions.cs
@@ -25,6 +25,7 @@ public static class ServicesExtensions
///
///
///
+ ///
///
public static IServiceCollection AddPetaPocoDataAccessServices(this IServiceCollection services, Action builder)
{
@@ -66,14 +67,14 @@ public static class ServicesExtensions
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
// 增加业务服务
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
return services;
}
}
diff --git a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs
index d21cae7f..8235c379 100644
--- a/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs
+++ b/src/blazor/admin/BootstrapAdmin.DataAccess.PetaPoco/Services/UserService.cs
@@ -131,6 +131,7 @@ class UserService : BaseDatabase, IUser
/// 创建手机用户
///
///
+ ///
///
///
///
diff --git a/src/blazor/admin/BootstrapAdmin.Web.Core/ExceptionFilter.cs b/src/blazor/admin/BootstrapAdmin.Web.Core/ExceptionFilter.cs
index 840129b4..1a27431d 100644
--- a/src/blazor/admin/BootstrapAdmin.Web.Core/ExceptionFilter.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web.Core/ExceptionFilter.cs
@@ -1,14 +1,32 @@
namespace BootstrapAdmin.Web.Core;
+///
+///
+///
public class ExceptionFilter
{
+ ///
+ ///
+ ///
public DateTime Star { get; set; }
+ ///
+ ///
+ ///
public DateTime End { get; set; }
+ ///
+ ///
+ ///
public string? UserId { get; set; }
+ ///
+ ///
+ ///
public string? ErrorPage { get; set; }
+ ///
+ ///
+ ///
public string? Category { get; set; }
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web.Core/IDict.cs b/src/blazor/admin/BootstrapAdmin.Web.Core/IDict.cs
index c863ba69..7f2f0a12 100644
--- a/src/blazor/admin/BootstrapAdmin.Web.Core/IDict.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web.Core/IDict.cs
@@ -1,123 +1,145 @@
using BootstrapAdmin.DataAccess.Models;
-namespace BootstrapAdmin.Web.Core
+namespace BootstrapAdmin.Web.Core;
+
+///
+/// Dict 字典表接口
+///
+public interface IDict
{
///
- /// Dict 字典表接口
+ ///
///
- public interface IDict
- {
+ ///
+ List GetAll();
- ///
- ///
- ///
- ///
- List GetAll();
+ ///
+ /// 获得 配置所有的 App 集合
+ ///
+ ///
+ Dictionary GetApps();
- ///
- /// 获得 配置所有的 App 集合
- ///
- ///
- Dictionary GetApps();
+ ///
+ /// 获得 配置所有的登录页集合
+ ///
+ ///
+ Dictionary GetLogins();
- ///
- /// 获得 配置所有的登录页集合
- ///
- ///
- Dictionary GetLogins();
+ ///
+ /// 获得 当前配置登录页
+ ///
+ ///
+ string GetCurrentLogin();
- ///
- /// 获得 当前配置登录页
- ///
- ///
- string GetCurrentLogin();
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SaveLogin(string login);
- bool SaveLogin(string login);
+ ///
+ /// 获得 配置所有的主题集合
+ ///
+ ///
+ Dictionary GetThemes();
- ///
- /// 获得 配置所有的主题集合
- ///
- ///
- Dictionary GetThemes();
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SaveTheme(string theme);
- ///
- ///
- ///
- ///
- ///
- bool SaveTheme(string theme);
+ ///
+ /// 获取当前系统配置是否为演示模式
+ ///
+ ///
+ bool IsDemo();
- ///
- /// 获取当前系统配置是否为演示模式
- ///
- ///
- bool IsDemo();
+ ///
+ /// 保存当前网站是否为演示系统
+ ///
+ ///
+ ///
+ bool SaveDemo(bool isDemo);
- ///
- /// 保存当前网站是否为演示系统
- ///
- ///
- ///
- bool SaveDemo(bool isDemo);
+ ///
+ /// 保存健康检查
+ ///
+ ///
+ bool SaveHealthCheck(bool enable = true);
- ///
- /// 保存健康检查
- ///
- ///
- bool SaveHealthCheck(bool enable = true);
+ ///
+ /// 获得当前授权码是否有效可更改网站设置
+ ///
+ ///
+ ///
+ bool AuthenticateDemo(string code);
- ///
- /// 获得当前授权码是否有效可更改网站设置
- ///
- ///
- ///
- bool AuthenticateDemo(string code);
+ ///
+ /// 获取 站点 Title 配置信息
+ ///
+ ///
+ string GetWebTitle();
- ///
- /// 获取 站点 Title 配置信息
- ///
- ///
- string GetWebTitle();
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SaveWebTitle(string title);
- ///
- ///
- ///
- ///
- ///
- bool SaveWebTitle(string title);
+ ///
+ /// 获取站点 Footer 配置信息
+ ///
+ ///
+ string GetWebFooter();
- ///
- /// 获取站点 Footer 配置信息
- ///
- ///
- string GetWebFooter();
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SaveWebFooter(string footer);
- ///
- ///
- ///
- ///
- ///
- bool SaveWebFooter(string footer);
+ ///
+ /// 获得 Cookie 登录持久化时长
+ ///
+ ///
+ int GetCookieExpiresPeriod();
- ///
- /// 获得 Cookie 登录持久化时长
- ///
- ///
- int GetCookieExpiresPeriod();
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SaveCookieExpiresPeriod(int expiresPeriod);
- ///
- ///
- ///
- ///
- ///
- bool SaveCookieExpiresPeriod(int expiresPeriod);
+ ///
+ ///
+ ///
+ ///
+ ///
+ string? GetProfileUrl(string appId);
- string? GetProfileUrl(string appId);
+ ///
+ ///
+ ///
+ ///
+ ///
+ string? GetSettingsUrl(string appId);
- string? GetSettingsUrl(string appId);
+ ///
+ ///
+ ///
+ ///
+ ///
+ string? GetNotificationUrl(string appId);
- string? GetNotificationUrl(string appId);
-
- string RetrieveIconFolderPath();
- }
+ ///
+ ///
+ ///
+ ///
+ string RetrieveIconFolderPath();
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web.Core/IException.cs b/src/blazor/admin/BootstrapAdmin.Web.Core/IException.cs
index 31681d37..2a183a42 100644
--- a/src/blazor/admin/BootstrapAdmin.Web.Core/IException.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web.Core/IException.cs
@@ -2,9 +2,26 @@
namespace BootstrapAdmin.Web.Core;
+///
+///
+///
public interface IException
{
+ ///
+ ///
+ ///
+ ///
+ ///
bool Log(Error exception);
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
(IEnumerable Items, int ItemsCount) GetAll(string? searchText, ExceptionFilter filter, int pageIndex, int pageItems, List sortList);
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web.Core/INavigation.cs b/src/blazor/admin/BootstrapAdmin.Web.Core/INavigation.cs
index 27b2961b..b54e246f 100644
--- a/src/blazor/admin/BootstrapAdmin.Web.Core/INavigation.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web.Core/INavigation.cs
@@ -1,30 +1,30 @@
using BootstrapAdmin.DataAccess.Models;
-namespace BootstrapAdmin.Web.Core
+namespace BootstrapAdmin.Web.Core;
+
+///
+///
+///
+public interface INavigation
{
///
///
///
- public interface INavigation
- {
- ///
- ///
- ///
- ///
- List GetAllMenus(string userName);
+ ///
+ List GetAllMenus(string userName);
- ///
- ///
- ///
- ///
- ///
- List GetMenusByRoleId(string? roleId);
+ ///
+ ///
+ ///
+ ///
+ ///
+ List GetMenusByRoleId(string? roleId);
- ///
- ///
- ///
- ///
- ///
- bool SaveMenusByRoleId(string? roleId, List menuIds);
- }
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SaveMenusByRoleId(string? roleId, List menuIds);
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs b/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs
index fed76d71..a782c180 100644
--- a/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web.Core/IUser.cs
@@ -76,6 +76,7 @@ public interface IUser
///
///
///
+ ///
///
///
///
diff --git a/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.Web.csproj b/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.Web.csproj
index 6997d44d..4fb7a65b 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.Web.csproj
+++ b/src/blazor/admin/BootstrapAdmin.Web/BootstrapAdmin.Web.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminAlert.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminAlert.razor.cs
index 1ff995c8..ac27a6c3 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminAlert.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminAlert.razor.cs
@@ -2,17 +2,32 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class AdminAlert
{
+ ///
+ ///
+ ///
[Parameter]
public string? Text { get; set; }
+ ///
+ ///
+ ///
[Parameter]
public RenderFragment? ChildContent { get; set; }
+ ///
+ ///
+ ///
[Parameter]
public Color Color { get; set; } = Color.Danger;
+ ///
+ ///
+ ///
[Parameter]
public bool IsShow { get; set; } = true;
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminLogin.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminLogin.razor.cs
index 27812209..986ae0a0 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminLogin.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminLogin.razor.cs
@@ -3,6 +3,9 @@ using Microsoft.JSInterop;
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class AdminLogin
{
private string? Title { get; set; }
@@ -19,6 +22,9 @@ public partial class AdminLogin
private string? PostUrl { get; set; }
+ ///
+ ///
+ ///
[Parameter]
public string? ReturnUrl { get; set; }
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor
index df0ab906..1f1ceec0 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor
@@ -7,7 +7,7 @@
ShowEmpty="true" EmptyText="暂无数据" EmptyImage="images/empty.svg"
UseInjectDataService="true" DataService="DataService" SortList="SortList"
OnQueryAsync="OnQueryAsync!" OnDeleteAsync="OnDeleteAsync!" OnSaveAsync="OnSaveAsync!"
- ShowSkeleton="true" ShowLoading="true" ShowSearch="ShowSearch"
+ ShowSkeleton="true" ShowLoading="ShowLoading" ShowSearch="ShowSearch"
ShowToolbar="ShowToolbar" ShowExtendButtons="ShowExtendButtons"
ShowCardView="true" ShowColumnList="true" ExtendButtonColumnWidth="@ExtendButtonColumnWidth"
CustomerSearchModel="CustomerSearchModel" SelectedRows="SelectedRows"
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor.cs
index 598e218a..dd4a62b4 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/AdminTable.razor.cs
@@ -82,6 +82,12 @@ namespace BootstrapAdmin.Web.Components
[Parameter]
public bool ShowToolbar { get; set; } = true;
+ ///
+ ///
+ ///
+ [Parameter]
+ public bool ShowLoading { get; set; } = false;
+
///
///
///
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/Assignment.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/Assignment.razor.cs
index 68e32e61..2bfdde34 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/Assignment.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/Assignment.razor.cs
@@ -1,5 +1,8 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class Assignment
{
private List InternalValue
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/AssignmentBase.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/AssignmentBase.cs
index fc920834..40b39d7d 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/AssignmentBase.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/AssignmentBase.cs
@@ -1,17 +1,30 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
+///
public abstract class AssignmentBase : ComponentBase
{
+ ///
+ ///
+ ///
[Parameter]
[EditorRequired]
[NotNull]
public List? Items { get; set; }
+ ///
+ ///
+ ///
[Parameter]
[EditorRequired]
[NotNull]
public List? Value { get; set; }
+ ///
+ ///
+ ///
[Parameter]
[EditorRequired]
[NotNull]
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/ErrorSearch.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/ErrorSearch.razor.cs
index d0e26b44..ad2325ce 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/ErrorSearch.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/ErrorSearch.razor.cs
@@ -24,6 +24,9 @@ namespace BootstrapAdmin.Web.Components
[Parameter]
public EventCallback ValueChanged { get; set; }
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/HealthCheckDetails.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/HealthCheckDetails.razor.cs
index 7bf37ee5..47a1424e 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/HealthCheckDetails.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/HealthCheckDetails.razor.cs
@@ -2,8 +2,14 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class HealthCheckDetails
{
+ ///
+ ///
+ ///
[Parameter]
[EditorRequired]
[NotNull]
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/MenusSearch.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/MenusSearch.razor.cs
index bbbef8a5..07fdca6f 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/MenusSearch.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/MenusSearch.razor.cs
@@ -6,6 +6,9 @@ using BootstrapAdmin.Web.Utils;
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class MenusSearch
{
[NotNull]
@@ -20,14 +23,22 @@ public partial class MenusSearch
private List? TargetItems { get; set; }
+ ///
+ ///
+ ///
[Parameter]
[NotNull]
public MenusSearchModel? Value { get; set; }
+ ///
+ ///
+ ///
[Parameter]
public EventCallback ValueChanged { get; set; }
-
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/NavigationTree.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/NavigationTree.razor.cs
index aadcf04e..d3202f73 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/NavigationTree.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/NavigationTree.razor.cs
@@ -3,6 +3,9 @@ using BootstrapAdmin.Web.Extensions;
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class NavigationTree
{
[NotNull]
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/SMSLogin.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/SMSLogin.razor.cs
index d75408de..02a73982 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/SMSLogin.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/SMSLogin.razor.cs
@@ -2,6 +2,9 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class SMSLogin : IDisposable
{
private bool IsSendCode { get; set; } = true;
@@ -64,6 +67,9 @@ public partial class SMSLogin : IDisposable
}
}
+ ///
+ ///
+ ///
public void Dispose()
{
Dispose(true);
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/TaskEditor.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/TaskEditor.razor.cs
index 828b8d80..a56438b5 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/TaskEditor.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/TaskEditor.razor.cs
@@ -2,12 +2,21 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class TaskEditor
{
+ ///
+ ///
+ ///
[Parameter]
[NotNull]
public TasksModel? Value { get; set; }
+ ///
+ ///
+ ///
[Parameter]
public EventCallback ValueChanged { get; set; }
@@ -16,6 +25,9 @@ public partial class TaskEditor
[NotNull]
private List? Items { get; set; }
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Components/UserLogin.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Components/UserLogin.razor.cs
index 3762bc2c..0e943c20 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Components/UserLogin.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Components/UserLogin.razor.cs
@@ -1,11 +1,17 @@
namespace BootstrapAdmin.Web.Components;
+///
+///
+///
public partial class UserLogin
{
private string? UserName { get; set; }
private string? Password { get; set; }
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Controllers/AccountController.cs b/src/blazor/admin/BootstrapAdmin.Web/Controllers/AccountController.cs
index 7f046f88..375f9a5f 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Controllers/AccountController.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Controllers/AccountController.cs
@@ -26,6 +26,7 @@ namespace BootstrapAdmin.Web.Controllers
/// User name.
/// Password.
/// Remember.
+ ///
///
///
///
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Controllers/api/LoginController.cs b/src/blazor/admin/BootstrapAdmin.Web/Controllers/api/LoginController.cs
index bc26a3d6..a8d5703a 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Controllers/api/LoginController.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Controllers/api/LoginController.cs
@@ -6,6 +6,9 @@ using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute;
namespace BootstrapAdmin.Web.Controllers.api;
+///
+///
+///
[Route("api/[controller]")]
[AllowAnonymous]
[ApiController]
@@ -14,8 +17,10 @@ public class LoginController : ControllerBase
///
/// 登录认证接口
///
- ///
///
+ ///
+ ///
+ ///
///
[HttpPost()]
public AuthenticateResult Post(LoginUser user, [FromQuery] bool mobile,
@@ -58,17 +63,35 @@ public class LoginController : ControllerBase
return null;
}
+ ///
+ ///
+ ///
public class AuthenticateResult
{
+ ///
+ ///
+ ///
public string? Error { get; set; }
+ ///
+ ///
+ ///
public bool Authenticated { get; set; }
}
+ ///
+ ///
+ ///
public class LoginUser
{
+ ///
+ ///
+ ///
public string? UserName { get; set; }
+ ///
+ ///
+ ///
public string? Password { get; set; }
}
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/ApplicationBuilderExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/ApplicationBuilderExtensions.cs
index c177c7fc..e128233a 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/ApplicationBuilderExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/ApplicationBuilderExtensions.cs
@@ -1,4 +1,4 @@
-namespace Microsoft.AspNetCore.Builder
+namespace BootstrapAdmin.Web.Extensions
{
///
///
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/CloudLoggerExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/CloudLoggerExtensions.cs
index 9e7d4a30..e570de76 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/CloudLoggerExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/CloudLoggerExtensions.cs
@@ -2,7 +2,7 @@
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Options;
-namespace Microsoft.Extensions.DependencyInjection
+namespace BootstrapAdmin.Web.Extensions
{
///
/// 邮件日志扩展方法
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/DialogExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/DialogExtensions.cs
index 73f179af..e5ecb6f1 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/DialogExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/DialogExtensions.cs
@@ -8,8 +8,14 @@ namespace BootstrapAdmin.Web.Extensions;
///
public static class DialogExtensions
{
+ ///
+ ///
+ ///
public static Task ShowAssignmentDialog(this DialogService dialogService, string title, List items, List value, Func> saveCallback, ToastService? toast) => dialogService.ShowDialog(title, items, value, saveCallback, toast);
+ ///
+ ///
+ ///
public static Task ShowNavigationDialog(this DialogService dialogService, string title, List items, List value, Func> saveCallback, ToastService? toast) => dialogService.ShowDialog(title, items, value, saveCallback, toast);
private static Task ShowDialog(this DialogService dialogService, string title, List items, List value, Func> saveCallback, ToastService? toast) where TBody : AssignmentBase => dialogService.ShowSaveDialog(title, async () =>
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/SelectedItemExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/SelectedItemExtensions.cs
index 82a37680..80f49d87 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/SelectedItemExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/SelectedItemExtensions.cs
@@ -17,21 +17,21 @@ public static class SelectedItemExtensions
///
///
///
- ///
+ ///
///
public static List ToSelectedItemList(this IEnumerable roles) => roles.Select(i => new SelectedItem { Value = i.Id!, Text = i.RoleName }).ToList();
///
///
///
- ///
+ ///
///
public static List ToSelectedItemList(this IEnumerable groups) => groups.Select(i => new SelectedItem { Value = i.Id!, Text = i.ToString() }).ToList();
///
///
///
- ///
+ ///
///
public static List ToSelectedItemList(this Dictionary dict) => dict.Select(i => new SelectedItem { Value = i.Key, Text = i.Value }).ToList();
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/ServicesExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/ServicesExtensions.cs
index 52137a7d..8eb2ed4c 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/ServicesExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/ServicesExtensions.cs
@@ -1,12 +1,11 @@
using BootstrapAdmin.Web.Core;
+using BootstrapAdmin.Web.HealthChecks;
using BootstrapAdmin.Web.Services;
using BootstrapAdmin.Web.Services.SMS;
using BootstrapAdmin.Web.Services.SMS.Tencent;
using BootstrapAdmin.Web.Utils;
-using PetaPoco;
-using PetaPoco.Providers;
-namespace Microsoft.Extensions.DependencyInjection
+namespace BootstrapAdmin.Web.Extensions
{
///
///
@@ -47,14 +46,26 @@ namespace Microsoft.Extensions.DependencyInjection
//});
// 增加 PetaPoco 数据服务
- services.AddPetaPocoDataAccessServices((provider, builder) =>
+ //services.AddPetaPocoDataAccessServices((provider, builder) =>
+ //{
+ // var configuration = provider.GetRequiredService();
+ // var connString = configuration.GetConnectionString("bb");
+ // builder.UsingProvider()
+ // .UsingConnectionString(connString);
+ //});
+
+ services.AddFreeSql((provider, builder) =>
{
var configuration = provider.GetRequiredService();
var connString = configuration.GetConnectionString("bb");
- builder.UsingProvider()
- .UsingConnectionString(connString);
+ builder.UseConnectionString(FreeSql.DataType.Sqlite, connString);
+#if DEBUG
+ //调试sql语句输出
+ builder.UseMonitorCommand(cmd => System.Console.WriteLine(cmd.CommandText));
+#endif
});
+
// 增加后台任务
services.AddTaskServices();
services.AddHostedService();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/TasksExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/TasksExtensions.cs
index deb69138..6e4e0ce3 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/TasksExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/TasksExtensions.cs
@@ -3,8 +3,14 @@ using Longbow.Tasks;
namespace BootstrapAdmin.Web.Extensions;
+///
+///
+///
public static class TasksExtensions
{
+ ///
+ ///
+ ///
public static List ToTasksModelList(this IEnumerable schedulers) => schedulers.Select(i => new TasksModel
{
Name = i.Name,
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Extensions/TreeItemExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/Extensions/TreeItemExtensions.cs
index 645c7072..0917dfaf 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Extensions/TreeItemExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Extensions/TreeItemExtensions.cs
@@ -2,8 +2,19 @@
namespace BootstrapAdmin.Web.Extensions;
+///
+///
+///
public static class TreeItemExtensions
{
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public static List ToTreeItemList(this IEnumerable navigations, List selectedItems, RenderFragment render, string? parentId = "0")
{
var trees = new List();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpClient.cs b/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpClient.cs
index 1621c6f6..9d9d3285 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpClient.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpClient.cs
@@ -14,6 +14,7 @@ public class GiteeHttpClient
/// 构造函数
///
///
+ ///
public GiteeHttpClient(HttpClient client, IHttpContextAccessor accessor)
{
client.Timeout = TimeSpan.FromSeconds(10);
diff --git a/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpHealthCheck.cs b/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpHealthCheck.cs
index ab753a44..82f8a1bb 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpHealthCheck.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/GiteeHttpHealthCheck.cs
@@ -14,7 +14,6 @@ class GiteeHttpHealthCheck : IHealthCheck
/// 构造函数
///
///
- ///
public GiteeHttpHealthCheck(GiteeHttpClient client)
{
Client = client;
diff --git a/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/HealthChecksBuilderExtensions.cs b/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/HealthChecksBuilderExtensions.cs
index 73b3a21c..2023ccf9 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/HealthChecksBuilderExtensions.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/HealthChecks/HealthChecksBuilderExtensions.cs
@@ -1,6 +1,4 @@
-using BootstrapAdmin.Web.HealthChecks;
-
-namespace Microsoft.Extensions.DependencyInjection;
+namespace BootstrapAdmin.Web.HealthChecks;
///
/// 健康检查扩展类
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Models/MenusSearchModel.cs b/src/blazor/admin/BootstrapAdmin.Web/Models/MenusSearchModel.cs
index 2bb830af..74ca657d 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Models/MenusSearchModel.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Models/MenusSearchModel.cs
@@ -3,11 +3,20 @@ using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.Web.Models;
+///
+///
+///
public class MenusSearchModel : ITableSearchModel
{
+ ///
+ ///
+ ///
[Display(Name = "名称")]
public string? Name { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "地址")]
public string? Url { get; set; }
@@ -35,6 +44,10 @@ public class MenusSearchModel : ITableSearchModel
[Display(Name = "所属应用")]
public string? Application { get; set; }
+ ///
+ ///
+ ///
+ ///
public IEnumerable GetSearchs()
{
var ret = new List();
@@ -70,6 +83,9 @@ public class MenusSearchModel : ITableSearchModel
return ret;
}
+ ///
+ ///
+ ///
public void Reset()
{
Name = null;
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Models/TasksModel.cs b/src/blazor/admin/BootstrapAdmin.Web/Models/TasksModel.cs
index 46491eaa..814834c0 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Models/TasksModel.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Models/TasksModel.cs
@@ -3,29 +3,53 @@ using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.Web.Models;
+///
+///
+///
public class TasksModel
{
+ ///
+ ///
+ ///
[Display(Name = "任务名称")]
[NotNull]
public string? Name { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "创建时间")]
public DateTimeOffset CreateTime { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "上次运行时间")]
public DateTimeOffset? LastRuntime { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "下次运行时间")]
public DateTimeOffset? NextRuntime { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "触发条件")]
[NotNull]
public string? Trigger { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "执行结果")]
[NotNull]
public TriggerResult LastRunResult { get; set; }
+ ///
+ ///
+ ///
[Display(Name = "任务状态")]
[NotNull]
public SchedulerStatus Status { get; set; }
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Account/Login.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Account/Login.razor.cs
index c3245b80..7cbab2c6 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Account/Login.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Account/Login.razor.cs
@@ -5,6 +5,9 @@
///
public partial class Login
{
+ ///
+ ///
+ ///
[SupplyParameterFromQuery]
[Parameter]
public string? ReturnUrl { get; set; }
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Exceptions.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Exceptions.razor.cs
index 6d376936..8a92c96a 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Exceptions.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Exceptions.razor.cs
@@ -5,6 +5,9 @@ using BootstrapAdmin.Web.Utils;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Exceptions
{
private List PageItemsSource { get; } = new List { 20, 40, 80, 100, 200 };
@@ -18,6 +21,9 @@ public partial class Exceptions
[NotNull]
private List? CategroyLookup { get; set; }
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Groups.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Groups.razor.cs
index c57f1ce8..7126c55e 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Groups.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Groups.razor.cs
@@ -4,6 +4,9 @@ using BootstrapAdmin.Web.Extensions;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Groups
{
[Inject]
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor
index 0a104500..a940af46 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor
@@ -12,7 +12,7 @@
+ ShowToolbar="false" ShowSearch="false" ShowLoading="true" OnQueryAsync="OnQueryAsync">
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs
index 6c23efc5..af57b0af 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Healths.razor.cs
@@ -9,6 +9,9 @@ using System.Text.Json.Serialization;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Healths
{
[Inject]
@@ -33,6 +36,9 @@ public partial class Healths
[NotNull]
private HttpClient? Client { get; set; }
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor
index 303df279..54afa373 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor
@@ -1,13 +1,13 @@
@page "/Admin/Menus"
-
+
-
+
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor.cs
index e59996f8..8aa9663b 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Menus.razor.cs
@@ -7,6 +7,9 @@ using BootstrapAdmin.Web.Utils;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Menus
{
[Inject]
@@ -74,6 +77,19 @@ public partial class Menus
{
var navs = NavigationService.GetAllMenus(AppContext.UserName);
var menus = navs.Where(m => m.ParentId == "0");
+
+ // 处理模糊查询
+ if (options.Searchs.Any())
+ {
+ menus = menus.Where(options.Searchs.GetFilterFunc(FilterLogic.Or));
+ }
+
+ // 处理 Filter 高级搜索
+ if (options.CustomerSearchs.Any() || options.Filters.Any())
+ {
+ menus = menus.Where(options.CustomerSearchs.Concat(options.Filters).GetFilterFunc());
+ }
+
foreach (var item in menus)
{
item.HasChildren = navs.Any(i => i.ParentId == item.Id);
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Profiles.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Profiles.razor.cs
index a6a4ad9e..15bf2614 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Profiles.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Profiles.razor.cs
@@ -6,15 +6,19 @@ using Microsoft.AspNetCore.Components.Forms;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Profiles
{
private bool IsDemo { get; set; }
- private string? ConfirmPassword { get; set; }
-
[NotNull]
private User? CurrentUser { get; set; }
+ ///
+ ///
+ ///
[Inject]
[NotNull]
public BootstrapAppContext? AppContext { get; set; }
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Roles.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Roles.razor.cs
index c886722c..5b6e4290 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Roles.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Roles.razor.cs
@@ -5,6 +5,9 @@ using BootstrapAdmin.Web.Services;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Roles
{
[Inject]
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Settings.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Settings.razor.cs
index e380e435..1a45f632 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Settings.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Settings.razor.cs
@@ -3,105 +3,107 @@ using BootstrapAdmin.Web.Core;
using BootstrapAdmin.Web.Extensions;
using Microsoft.AspNetCore.Components.Forms;
-namespace BootstrapAdmin.Web.Pages.Admin
+namespace BootstrapAdmin.Web.Pages.Admin;
+
+///
+///
+///
+public partial class Settings
{
- public partial class Settings
+ private bool IsDemo { get; set; }
+
+ [NotNull]
+ private AppInfo? AppInfo { get; set; }
+
+ [NotNull]
+ private List? Logins { get; set; }
+
+ [NotNull]
+ private List? Themes { get; set; }
+
+ [Inject]
+ [NotNull]
+ private IDict? DictService { get; set; }
+
+ [Inject]
+ [NotNull]
+ private IUser? UserService { get; set; }
+
+ [Inject]
+ [NotNull]
+ private ToastService? ToastService { get; set; }
+
+ ///
+ ///
+ ///
+ protected override void OnInitialized()
{
- private bool IsDemo { get; set; }
+ base.OnInitialized();
- [NotNull]
- private AppInfo? AppInfo { get; set; }
-
- [NotNull]
- private List? Logins { get; set; }
-
- [NotNull]
- private List? Themes { get; set; }
-
- [Inject]
- [NotNull]
- private IDict? DictService { get; set; }
-
- [Inject]
- [NotNull]
- private IUser? UserService { get; set; }
-
- [Inject]
- [NotNull]
- private ToastService? ToastService { get; set; }
-
- ///
- ///
- ///
- protected override void OnInitialized()
+ IsDemo = DictService.IsDemo();
+ Logins = DictService.GetLogins().ToSelectedItemList();
+ Themes = DictService.GetThemes().ToSelectedItemList();
+ AppInfo = new()
{
- base.OnInitialized();
+ IsDemo = IsDemo,
+ AuthCode = "123789",
+ Title = DictService.GetWebTitle(),
+ Footer = DictService.GetWebFooter(),
+ Login = DictService.GetCurrentLogin()
+ };
+ }
- IsDemo = DictService.IsDemo();
- Logins = DictService.GetLogins().ToSelectedItemList();
- Themes = DictService.GetThemes().ToSelectedItemList();
- AppInfo = new()
- {
- IsDemo = IsDemo,
- AuthCode = "123789",
- Title = DictService.GetWebTitle(),
- Footer = DictService.GetWebFooter(),
- Login = DictService.GetCurrentLogin()
- };
+ private async Task ShowToast(bool result, string title)
+ {
+ if (result)
+ {
+ await ToastService.Success(title, $"保存{title}成功");
}
-
- private async Task ShowToast(bool result, string title)
+ else
{
- if (result)
- {
- await ToastService.Success(title, $"保存{title}成功");
- }
- else
- {
- await ToastService.Error(title, $"保存{title}失败");
- }
- }
-
- private async Task OnSaveTitle(EditContext context)
- {
- var ret = DictService.SaveWebTitle(AppInfo.Title);
- await ShowToast(ret, "网站标题");
- }
-
- private async Task OnSaveFooter(EditContext context)
- {
- var ret = DictService.SaveWebTitle(AppInfo.Title);
- await ShowToast(ret, "网站页脚");
- }
-
- private async Task OnSaveLogin(EditContext context)
- {
- var ret = DictService.SaveLogin(AppInfo.Login);
- await ShowToast(ret, "登录界面");
- }
-
- private async Task OnSaveAuthUrl(EditContext context)
- {
- var ret = DictService.SaveLogin(AppInfo.Login);
- await ShowToast(ret, "授权后台地址");
- }
-
- private async Task OnSaveTheme(EditContext context)
- {
- var ret = DictService.SaveLogin(AppInfo.Login);
- await ShowToast(ret, "网站主题");
- }
-
- private async Task OnSaveDemo(EditContext context)
- {
- var ret = false;
- if (DictService.AuthenticateDemo(AppInfo.AuthCode))
- {
- IsDemo = AppInfo.IsDemo;
- ret = DictService.SaveDemo(IsDemo);
- StateHasChanged();
- }
- await ShowToast(ret, "演示系统");
+ await ToastService.Error(title, $"保存{title}失败");
}
}
+
+ private async Task OnSaveTitle(EditContext context)
+ {
+ var ret = DictService.SaveWebTitle(AppInfo.Title);
+ await ShowToast(ret, "网站标题");
+ }
+
+ private async Task OnSaveFooter(EditContext context)
+ {
+ var ret = DictService.SaveWebTitle(AppInfo.Title);
+ await ShowToast(ret, "网站页脚");
+ }
+
+ private async Task OnSaveLogin(EditContext context)
+ {
+ var ret = DictService.SaveLogin(AppInfo.Login);
+ await ShowToast(ret, "登录界面");
+ }
+
+ private async Task OnSaveAuthUrl(EditContext context)
+ {
+ var ret = DictService.SaveLogin(AppInfo.Login);
+ await ShowToast(ret, "授权后台地址");
+ }
+
+ private async Task OnSaveTheme(EditContext context)
+ {
+ var ret = DictService.SaveLogin(AppInfo.Login);
+ await ShowToast(ret, "网站主题");
+ }
+
+ private async Task OnSaveDemo(EditContext context)
+ {
+ var ret = false;
+ if (DictService.AuthenticateDemo(AppInfo.AuthCode))
+ {
+ IsDemo = AppInfo.IsDemo;
+ ret = DictService.SaveDemo(IsDemo);
+ StateHasChanged();
+ }
+ await ShowToast(ret, "演示系统");
+ }
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Tasks.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Tasks.razor.cs
index 7d91579f..26976012 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Tasks.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Tasks.razor.cs
@@ -5,6 +5,9 @@ using Longbow.Tasks;
namespace BootstrapAdmin.Web.Pages.Admin;
+///
+///
+///
public partial class Tasks
{
private List SelectedRows { get; set; } = new List();
@@ -29,6 +32,9 @@ public partial class Tasks
private List SortList { get; } = new List() { "Name", "LastRuntime desc" };
+ ///
+ ///
+ ///
protected override void OnInitialized()
{
base.OnInitialized();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor
index 1751aafb..b6f6e24d 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor
@@ -1,6 +1,9 @@
@page "/Admin/Users"
-
+
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs
index a891ef41..344e3007 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Pages/Admin/Users.razor.cs
@@ -66,4 +66,9 @@ public partial class Users
return Task.FromResult(ret);
}, ToastService);
}
+
+ private Task OnSaveAsync(User user, ItemChangedType itemChangedType)
+ {
+ return Task.FromResult(UserService.SaveUser(user.UserName, user.DisplayName, user.NewPassword));
+ }
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Program.cs b/src/blazor/admin/BootstrapAdmin.Web/Program.cs
index db99cd10..d5d7898c 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Program.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Program.cs
@@ -1,4 +1,6 @@
-var builder = WebApplication.CreateBuilder(args);
+using BootstrapAdmin.Web.Extensions;
+
+var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Utils/ExceptionsHelper.cs b/src/blazor/admin/BootstrapAdmin.Web/Utils/ExceptionsHelper.cs
index a20fc449..7ccb98cb 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Utils/ExceptionsHelper.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Utils/ExceptionsHelper.cs
@@ -14,6 +14,7 @@ public static class ExceptionsHelper
///
///
///
+ ///
///
///
///
@@ -50,8 +51,8 @@ public static class ExceptionsHelper
LogTime = DateTime.Now,
Category = category
};
- var expceptionService = provider.GetRequiredService();
- expceptionService.Log(exception);
+ //var expceptionService = provider.GetRequiredService();
+ //expceptionService.Log(exception);
}
}
}
diff --git a/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs b/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs
index e9d9834c..50dcb6eb 100644
--- a/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs
+++ b/src/blazor/admin/BootstrapAdmin.Web/Validators/UserNameValidator.cs
@@ -3,8 +3,14 @@ using System.ComponentModel.DataAnnotations;
namespace BootstrapAdmin.Web.Validators;
+///
+///
+///
public class UserNameValidator : IValidator
{
+ ///
+ ///
+ ///
public string? ErrorMessage { get; set; }
private IUser UserService { get; }