From f3382f9c8e4008afe50a070b918df871cd4a57b4 Mon Sep 17 00:00:00 2001 From: NoahLan <6995syu@163.com> Date: Thu, 9 May 2024 22:30:33 +0800 Subject: [PATCH] =?UTF-8?q?wip:=20=E8=A7=A3=E5=86=B3=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=AE=A1=E7=90=86+=E7=9F=AD=E4=BF=A1=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E3=80=82=E4=BC=98=E5=8C=96=E5=A4=A7=E9=83=A8=E5=88=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=90=AF=E5=8A=A8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Abp/NPinHttpExceptionStatusCodeFinder.cs | 28 + .../NPinFrameworkAspNetCoreModule.cs | 24 +- .../DbConnOptions.cs | 208 ++--- .../NPinFrameworkSqlSugarCoreModule.cs | 218 +++-- .../Repositories/SqlSugarRepository.cs | 859 +++++++++--------- .../SqlSugarDbConnectionCreator.cs | 239 ++--- .../SqlSugarDbContext.cs | 573 ++++++------ .../UnitOfWorkSqlSugarDbContextProvider.cs | 273 +++--- .../AuditLogInfoToAuditLogConverter.cs | 175 ++-- .../AuditingStore.cs | 119 +-- .../Entities/AuditLogActionEntity.cs | 100 +- .../Entities/AuditLogAggregateRoot.cs | 220 ++--- .../Entities/EntityChangeEntity.cs | 124 +-- .../Entities/EntityPropertyChangeEntity.cs | 98 +- .../Entities/SettingEntity.cs | 39 +- ....Framework.SettingManagement.Domain.csproj | 4 + .../SettingManager.cs | 21 +- .../Store/SettingManagementStore.cs | 7 +- .../TenantService.cs | 293 +++--- .../TenantAggregateRoot.cs | 98 +- .../Consts/ConfigConst.cs | 29 +- .../Enums/SmsEnum.cs | 42 +- .../Model/AliyunConfigModel.cs | 24 - .../Model/SmsConfigModel.cs | 180 ++-- .../Model/TencentConfigModel.cs | 31 - .../Authorization/SocialAggregateRoot.cs | 90 +- .../Entities/AnnouncementEntity.cs | 62 +- .../Entities/ConfigEntity.cs | 66 +- .../Entities/FileAggregateRoot.cs | 80 +- .../Entities/LoginLogEntity.cs | 161 ++-- .../Entities/OrganizationEntity.cs | 90 +- .../Entities/PostEntity.cs | 58 +- .../Entities/RoleEntity.cs | 82 +- .../Entities/RoleOrganizationEntity.cs | 30 +- .../Entities/UserEntity.cs | 3 +- .../Entities/UserMetaEntity.cs | 46 +- .../Entities/UserOrganizationEntity.cs | 30 +- .../Entities/UserPostEntity.cs | 32 +- .../Entities/UserRoleEntity.cs | 32 +- .../Managers/SmsManager.cs | 205 ++--- .../NPin.Framework.Upms.Domain.csproj | 1 + .../NPinFrameworkUpmsDomainModule.cs | 70 +- .../OperLog/OperationLogEntity.cs | 168 ++-- .../Settings/UpmsSettingManagementProvider.cs | 17 + .../Settings/UpmsSettingManagerExtensions.cs | 23 + .../Settings/UpmsStaticSettingProvider.cs | 20 + .../Sms/Handler/AliyunSmsHandler.cs | 54 ++ .../Sms/Handler/TencentSmsHandler.cs | 64 ++ .../NPin.Framework.Upms.Domain/Sms/ISms.cs | 26 +- .../DataSeeds/SmsConfigDataSeed.cs | 46 + .../NPin.Framework.Upms.SqlSugarCore.csproj | 21 +- .../NPinFrameworkUpmsSqlSugarCoreModule.cs | 39 +- .../NPinUpmsDbContext.cs | 96 +- .../{ => Repositories}/ConfigRepository.cs | 58 +- src/NPin.SqlSugarCore/NPinDbContext.cs | 20 +- .../NPinSqlSugarCoreModule.cs | 56 +- src/NPin.Web/NPinWebModule.cs | 2 +- src/NPin.Web/Program.cs | 2 +- src/NPin.Web/Properties/launchSettings.json | 39 +- src/NPin.Web/appsettings.json | 4 +- 60 files changed, 3141 insertions(+), 2778 deletions(-) create mode 100644 framework/NPin.Framework.AspNetCore/Abp/NPinHttpExceptionStatusCodeFinder.cs delete mode 100644 module/upms/NPin.Framework.Upms.Domain.Shared/Model/AliyunConfigModel.cs delete mode 100644 module/upms/NPin.Framework.Upms.Domain.Shared/Model/TencentConfigModel.cs create mode 100644 module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagementProvider.cs create mode 100644 module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagerExtensions.cs create mode 100644 module/upms/NPin.Framework.Upms.Domain/Settings/UpmsStaticSettingProvider.cs create mode 100644 module/upms/NPin.Framework.Upms.Domain/Sms/Handler/AliyunSmsHandler.cs create mode 100644 module/upms/NPin.Framework.Upms.Domain/Sms/Handler/TencentSmsHandler.cs create mode 100644 module/upms/NPin.Framework.Upms.SqlSugarCore/DataSeeds/SmsConfigDataSeed.cs rename module/upms/NPin.Framework.Upms.SqlSugarCore/{ => Repositories}/ConfigRepository.cs (91%) diff --git a/framework/NPin.Framework.AspNetCore/Abp/NPinHttpExceptionStatusCodeFinder.cs b/framework/NPin.Framework.AspNetCore/Abp/NPinHttpExceptionStatusCodeFinder.cs new file mode 100644 index 0000000..4ba372a --- /dev/null +++ b/framework/NPin.Framework.AspNetCore/Abp/NPinHttpExceptionStatusCodeFinder.cs @@ -0,0 +1,28 @@ +using System.Net; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.ExceptionHandling; + +namespace NPin.Framework.AspNetCore.Abp; + +/// +/// NPin框架自定义 HttpStatusCode 处理器 +/// 将 IBusinessException 与 IUserFriendlyException 默认返回403改为500 +/// +public class NPinHttpExceptionStatusCodeFinder : DefaultHttpExceptionStatusCodeFinder +{ + public NPinHttpExceptionStatusCodeFinder(IOptions options) : base(options) + { + } + + public override HttpStatusCode GetStatusCode(HttpContext httpContext, Exception exception) + { + switch (exception) + { + case IBusinessException _: + return HttpStatusCode.InternalServerError; + default: + return base.GetStatusCode(httpContext, exception); + } + } +} \ No newline at end of file diff --git a/framework/NPin.Framework.AspNetCore/NPinFrameworkAspNetCoreModule.cs b/framework/NPin.Framework.AspNetCore/NPinFrameworkAspNetCoreModule.cs index f2a55f6..a2839fb 100644 --- a/framework/NPin.Framework.AspNetCore/NPinFrameworkAspNetCoreModule.cs +++ b/framework/NPin.Framework.AspNetCore/NPinFrameworkAspNetCoreModule.cs @@ -1,9 +1,17 @@ -using NPin.Framework.Core; -using Volo.Abp.Modularity; - -namespace NPin.Framework.AspNetCore; - -[DependsOn(typeof(NPinFrameworkCoreModule))] -public class NPinFrameworkAspNetCoreModule : AbpModule -{ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NPin.Framework.AspNetCore.Abp; +using NPin.Framework.Core; +using Volo.Abp.AspNetCore.ExceptionHandling; + +namespace NPin.Framework.AspNetCore; + +[DependsOn(typeof(NPinFrameworkCoreModule))] +public class NPinFrameworkAspNetCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.Replace(new ServiceDescriptor(typeof(IHttpExceptionStatusCodeFinder), + typeof(NPinHttpExceptionStatusCodeFinder), ServiceLifetime.Transient)); + } } \ No newline at end of file diff --git a/framework/NPin.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs b/framework/NPin.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs index a7eb463..330f426 100644 --- a/framework/NPin.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs +++ b/framework/NPin.Framework.SqlSugarCore.Abstractions/DbConnOptions.cs @@ -1,105 +1,105 @@ -using SqlSugar; - -namespace NPin.Framework.SqlSugarCore.Abstractions; - -public class DbConnOptions -{ - /// - /// 连接字符串 必填 - /// - public string? Url { get; set; } - - /// - /// 数据库类型 - /// - public DbType? DbType { get; set; } - - /// - /// 开启种子数据 - /// - public bool EnabledDbSeed { get; set; } = false; - - /// - /// 开启 CodeFirst 自动化表结构 - /// - public bool EnabledCodeFirst { get; set; } = false; - - /// - /// 开启sql日志 - /// - public bool EnabledSqlLog { get; set; } = true; - - /// - /// 实体程序集 - /// - public List? EntityAssembly { get; set; } - - /// - /// 开启读写分离 - /// - public bool EnabledReadWrite { get; set; } = false; - - /// - /// 读写分离 - /// - public List? ReadUrl { get; set; } - - /// - /// 开启Saas多租户 - /// - public bool EnabledSaasMultiTenancy { get; set; } = false; - - - /// - /// 默认租户库连接,如果不填,那就是默认库的地址 - /// - public string? MasterSaasMultiTenancyUrl { get; set; } - - - /// - /// Saas租户连接 - /// - public List? SaasMultiTenancy { get; set; } - - public static string MasterTenantName = "Master"; - public static string DefaultTenantName = "Default"; - - public SaasMultiTenancyOptions GetDefaultSaasMultiTenancy() - { - return new SaasMultiTenancyOptions { Name = DefaultTenantName, Url = Url }; - } - - public SaasMultiTenancyOptions? GetDefaultMasterSaasMultiTenancy() - { - if (EnabledSaasMultiTenancy == false) - { - return null; - } - - if (string.IsNullOrEmpty(MasterSaasMultiTenancyUrl)) - { - return new SaasMultiTenancyOptions { Name = MasterTenantName, Url = Url }; - } - else - { - return new SaasMultiTenancyOptions() - { - Name = MasterTenantName, - Url = MasterSaasMultiTenancyUrl - }; - } - } -} - -public class SaasMultiTenancyOptions -{ - /// - /// 租户名称标识 - /// - public string Name { get; set; } - - /// - /// 连接Url - /// - public string Url { get; set; } +using SqlSugar; + +namespace NPin.Framework.SqlSugarCore.Abstractions; + +public class DbConnOptions +{ + /// + /// 连接字符串 必填 + /// + public string? Url { get; set; } + + /// + /// 数据库类型 + /// + public DbType? DbType { get; set; } + + /// + /// 开启种子数据 + /// + public bool EnabledDbSeed { get; set; } = false; + + /// + /// 开启 CodeFirst 自动化表结构 + /// + public bool EnabledCodeFirst { get; set; } = false; + + /// + /// 开启sql日志 + /// + public bool EnabledSqlLog { get; set; } = true; + + /// + /// 实体程序集 + /// + public List? EntityAssembly { get; set; } + + /// + /// 开启读写分离 + /// + public bool EnabledReadWrite { get; set; } = false; + + /// + /// 读写分离 + /// + public List? ReadUrl { get; set; } + + /// + /// 开启Saas多租户 + /// + public bool EnabledSaasMultiTenancy { get; set; } = false; + + + /// + /// 默认租户库连接,如果不填,那就是默认库的地址 + /// + public string? MasterSaasMultiTenancyUrl { get; set; } + + + /// + /// Saas租户连接 + /// + public List? SaasMultiTenancy { get; set; } + + public static string MasterTenantName = "Master"; + public static string DefaultTenantName = "Default"; + + public SaasMultiTenancyOptions GetDefaultSaasMultiTenancy() + { + return new SaasMultiTenancyOptions { Name = DefaultTenantName, Url = Url }; + } + + public SaasMultiTenancyOptions? GetMasterSaasMultiTenancy() + { + if (EnabledSaasMultiTenancy == false) + { + return null; + } + + if (string.IsNullOrEmpty(MasterSaasMultiTenancyUrl)) + { + return new SaasMultiTenancyOptions { Name = MasterTenantName, Url = Url }; + } + else + { + return new SaasMultiTenancyOptions() + { + Name = MasterTenantName, + Url = MasterSaasMultiTenancyUrl + }; + } + } +} + +public class SaasMultiTenancyOptions +{ + /// + /// 租户名称标识 + /// + public string Name { get; set; } + + /// + /// 连接Url + /// + public string Url { get; set; } } \ No newline at end of file diff --git a/framework/NPin.Framework.SqlSugarCore/NPinFrameworkSqlSugarCoreModule.cs b/framework/NPin.Framework.SqlSugarCore/NPinFrameworkSqlSugarCoreModule.cs index affb446..585f2f7 100644 --- a/framework/NPin.Framework.SqlSugarCore/NPinFrameworkSqlSugarCoreModule.cs +++ b/framework/NPin.Framework.SqlSugarCore/NPinFrameworkSqlSugarCoreModule.cs @@ -1,94 +1,126 @@ -using System.Reflection; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; -using NPin.Framework.SqlSugarCore.Abstractions; -using NPin.Framework.SqlSugarCore.Repositories; -using NPin.Framework.SqlSugarCore.Uow; -using SqlSugar; -using Volo.Abp; -using Volo.Abp.Data; -using Volo.Abp.Domain; -using Volo.Abp.Domain.Repositories; -using Volo.Abp.Modularity; - -namespace NPin.Framework.SqlSugarCore; - -[DependsOn(typeof(AbpDddDomainModule))] -public class NPinFrameworkSqlSugarCoreModule : AbpModule -{ - public override Task ConfigureServicesAsync(ServiceConfigurationContext context) - { - var service = context.Services; - var configuration = service.GetConfiguration(); - Configure(configuration.GetSection("DbConnOptions")); - - // 开放 sqlSugarClient - service.TryAddScoped(); - // 不开放 sqlSugarClient - //service.AddTransient(x => x.GetRequiredService().SqlSugarClient); - - service.AddTransient(typeof(IRepository<>), typeof(SqlSugarRepository<>)); - service.AddTransient(typeof(IRepository<,>), typeof(SqlSugarRepository<,>)); - service.AddTransient(typeof(ISqlSugarRepository<>), typeof(SqlSugarRepository<>)); - service.AddTransient(typeof(ISqlSugarRepository<,>), typeof(SqlSugarRepository<,>)); - - service.AddTransient(typeof(ISugarDbContextProvider<>), typeof(UnitOfWorkSqlSugarDbContextProvider<>)); - - return Task.CompletedTask; - } - - public override async Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) - { - // CodeFirst & DataSeed - var service = context.ServiceProvider; - var options = service.GetRequiredService>().Value; - - if (options.EnabledCodeFirst) - { - CodeFirst(service); - } - - if (options.EnabledDbSeed) - { - await DataSeedAsync(service); - } - } - - /// - /// CodeFirst 建库建表 - /// - /// - private void CodeFirst(IServiceProvider service) - { - var moduleContainer = service.GetRequiredService(); - var db = service.GetRequiredService().SqlSugarClient; - - // 尝试创建数据库 - db.DbMaintenance.CreateDatabase(); - - var types = new List(); - foreach (var module in moduleContainer.Modules) - { - types.AddRange(module.Assembly.GetTypes() - .Where(x => x.GetCustomAttribute() == null) - .Where(x => x.GetCustomAttribute() != null) - .Where(x => x.GetCustomAttribute() is null)); - } - - if (types.Count > 0) - { - db.CopyNew().CodeFirst.InitTables(types.ToArray()); - } - } - - /// - /// 同步种子数据 - /// - /// - private async Task DataSeedAsync(IServiceProvider service) - { - var dataSeeder = service.GetRequiredService(); - await dataSeeder.SeedAsync(); - } +using System.Reflection; +using System.Text; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using NPin.Framework.SqlSugarCore.Abstractions; +using NPin.Framework.SqlSugarCore.Repositories; +using NPin.Framework.SqlSugarCore.Uow; +using SqlSugar; +using Volo.Abp.Data; +using Volo.Abp.Domain; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Guids; + +namespace NPin.Framework.SqlSugarCore; + +[DependsOn(typeof(AbpDddDomainModule))] +public class NPinFrameworkSqlSugarCoreModule : AbpModule +{ + public override Task ConfigureServicesAsync(ServiceConfigurationContext context) + { + var service = context.Services; + var configuration = service.GetConfiguration(); + Configure(configuration.GetSection("DbConnOptions")); + + // 开放 sqlSugarClient + service.TryAddScoped(); + // 不开放 sqlSugarClient + //service.AddTransient(x => x.GetRequiredService().SqlSugarClient); + + service.AddTransient(typeof(IRepository<>), typeof(SqlSugarRepository<>)); + service.AddTransient(typeof(IRepository<,>), typeof(SqlSugarRepository<,>)); + service.AddTransient(typeof(ISqlSugarRepository<>), typeof(SqlSugarRepository<>)); + service.AddTransient(typeof(ISqlSugarRepository<,>), typeof(SqlSugarRepository<,>)); + + service.AddTransient(typeof(ISugarDbContextProvider<>), typeof(UnitOfWorkSqlSugarDbContextProvider<>)); + + return Task.CompletedTask; + } + + public override async Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) + { + // CodeFirst & DataSeed + var service = context.ServiceProvider; + var options = service.GetRequiredService>().Value; + + Configure(opt => + { + switch (options.DbType) + { + case DbType.PostgreSQL: + case DbType.MySql: + opt.DefaultSequentialGuidType = SequentialGuidType.SequentialAsString; + break; + case DbType.Oracle: + opt.DefaultSequentialGuidType = SequentialGuidType.SequentialAsBinary; + break; + default: + opt.DefaultSequentialGuidType = SequentialGuidType.SequentialAtEnd; + break; + } + }); + + var logger = service.GetRequiredService>(); + + StringBuilder sb = new StringBuilder(); + sb.AppendLine(); + sb.AppendLine("==========NPin-SQL配置:=========="); + sb.AppendLine($"数据库连接字符串:{options.Url}"); + sb.AppendLine($"数据库类型:{options.DbType.ToString()}"); + sb.AppendLine($"是否开启种子数据:{options.EnabledDbSeed}"); + sb.AppendLine($"是否开启CodeFirst:{options.EnabledCodeFirst}"); + sb.AppendLine($"是否开启Saas多租户:{options.EnabledSaasMultiTenancy}"); + sb.AppendLine("==============================="); + + logger.LogInformation(sb.ToString()); + + if (options.EnabledCodeFirst) + { + CodeFirst(service); + } + + if (options.EnabledDbSeed) + { + await DataSeedAsync(service); + } + } + + /// + /// CodeFirst 建库建表 + /// + /// + private void CodeFirst(IServiceProvider service) + { + var moduleContainer = service.GetRequiredService(); + var db = service.GetRequiredService().SqlSugarClient; + + // 尝试创建数据库 + db.DbMaintenance.CreateDatabase(); + + var types = new List(); + foreach (var module in moduleContainer.Modules) + { + types.AddRange(module.Assembly.GetTypes() + .Where(x => x.GetCustomAttribute() == null) + .Where(x => x.GetCustomAttribute() != null) + .Where(x => x.GetCustomAttribute() is null)); + } + + if (types.Count > 0) + { + db.CopyNew().CodeFirst.InitTables(types.ToArray()); + } + } + + /// + /// 同步种子数据 + /// + /// + private async Task DataSeedAsync(IServiceProvider service) + { + var dataSeeder = service.GetRequiredService(); + await dataSeeder.SeedAsync(); + } } \ No newline at end of file diff --git a/framework/NPin.Framework.SqlSugarCore/Repositories/SqlSugarRepository.cs b/framework/NPin.Framework.SqlSugarCore/Repositories/SqlSugarRepository.cs index 8255279..4f451d6 100644 --- a/framework/NPin.Framework.SqlSugarCore/Repositories/SqlSugarRepository.cs +++ b/framework/NPin.Framework.SqlSugarCore/Repositories/SqlSugarRepository.cs @@ -1,430 +1,431 @@ -using System.Linq.Expressions; -using NPin.Framework.Core.Helper; -using NPin.Framework.SqlSugarCore.Abstractions; -using SqlSugar; -using Volo.Abp; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Domain.Repositories; -using Volo.Abp.Linq; - -namespace NPin.Framework.SqlSugarCore.Repositories; - -public class SqlSugarRepository : ISqlSugarRepository, IRepository - where TEntity : class, IEntity, new() -{ - public ISqlSugarClient Db => GetDbContextAsync().Result; - - public ISugarQueryable DbQueryable => GetDbContextAsync().Result.Queryable(); - - private ISugarDbContextProvider _sugarDbContextProvider; - public IAsyncQueryableExecuter AsyncExecuter { get; } - - public bool? IsChangeTrackingEnabled => false; - - public SqlSugarRepository(ISugarDbContextProvider sugarDbContextProvider) - { - _sugarDbContextProvider = sugarDbContextProvider; - } - - public virtual async Task GetDbContextAsync() - { - var db = (await _sugarDbContextProvider.GetDbContextAsync()).SqlSugarClient; - return db; - } - - public virtual async Task> GetDbSimpleClientAsync() - { - var db = await GetDbContextAsync(); - return new SimpleClient(db); - } - - #region Abp模块 - - public virtual async Task FindAsync(Expression> predicate, bool includeDetails = true, - CancellationToken cancellationToken = default) - { - return await GetFirstAsync(predicate); - } - - public virtual async Task GetAsync(Expression> predicate, bool includeDetails = true, - CancellationToken cancellationToken = default) - { - return await GetFirstAsync(predicate); - } - - public virtual async Task DeleteAsync(Expression> predicate, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await this.DeleteAsync(predicate); - } - - public virtual async Task DeleteDirectAsync(Expression> predicate, - CancellationToken cancellationToken = default) - { - await this.DeleteAsync(predicate); - } - - public IQueryable WithDetails() - { - throw new NotImplementedException(); - } - - public IQueryable WithDetails(params Expression>[] propertySelectors) - { - throw new NotImplementedException(); - } - - public Task> WithDetailsAsync() - { - throw new NotImplementedException(); - } - - public Task> WithDetailsAsync(params Expression>[] propertySelectors) - { - throw new NotImplementedException(); - } - - public Task> GetQueryableAsync() - { - throw new NotImplementedException(); - } - - public virtual async Task> GetListAsync(Expression> predicate, - bool includeDetails = false, CancellationToken cancellationToken = default) - { - return await GetListAsync(predicate); - } - - public virtual async Task InsertAsync(TEntity entity, bool autoSave = false, - CancellationToken cancellationToken = default) - { - return await InsertReturnEntityAsync(entity); - } - - public virtual async Task InsertManyAsync(IEnumerable entities, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await InsertRangeAsync(entities.ToList()); - } - - public virtual async Task UpdateAsync(TEntity entity, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await UpdateAsync(entity); - return entity; - } - - public virtual async Task UpdateManyAsync(IEnumerable entities, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await UpdateRangeAsync(entities.ToList()); - } - - public virtual async Task DeleteAsync(TEntity entity, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await DeleteAsync(entity); - } - - public virtual async Task DeleteManyAsync(IEnumerable entities, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await DeleteAsync(entities.ToList()); - } - - public virtual async Task> GetListAsync(bool includeDetails = false, - CancellationToken cancellationToken = default) - { - return await GetListAsync(); - } - - public virtual async Task GetCountAsync(CancellationToken cancellationToken = default) - { - return await this.CountAsync(); - } - - public virtual async Task> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, - bool includeDetails = false, CancellationToken cancellationToken = default) - { - return await GetPageListAsync(_ => true, skipCount, maxResultCount); - } - - #endregion - - #region 内置DB快捷操作 - - public virtual async Task> AsDeleteable() - { - return (await GetDbSimpleClientAsync()).AsDeleteable(); - } - - public virtual async Task> AsInsertable(List insertObjs) - { - return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs); - } - - public virtual async Task> AsInsertable(TEntity insertObj) - { - return (await GetDbSimpleClientAsync()).AsInsertable(insertObj); - } - - public virtual async Task> AsInsertable(TEntity[] insertObjs) - { - return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs); - } - - public virtual async Task> AsQueryable() - { - return (await GetDbSimpleClientAsync()).AsQueryable(); - } - - public virtual async Task AsSugarClient() - { - return (await GetDbSimpleClientAsync()).AsSugarClient(); - } - - public virtual async Task AsTenant() - { - return (await GetDbSimpleClientAsync()).AsTenant(); - } - - public virtual async Task> AsUpdateable(List updateObjs) - { - return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs); - } - - public virtual async Task> AsUpdateable(TEntity updateObj) - { - return (await GetDbSimpleClientAsync()).AsUpdateable(updateObj); - } - - public virtual async Task> AsUpdateable() - { - return (await GetDbSimpleClientAsync()).AsUpdateable(); - } - - public virtual async Task> AsUpdateable(TEntity[] updateObjs) - { - return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs); - } - - #endregion - - #region SimpleClient模块 - - public virtual async Task CountAsync(Expression> whereExpression) - { - return await (await GetDbSimpleClientAsync()).CountAsync(whereExpression); - } - - public virtual async Task DeleteAsync(TEntity deleteObj) - { - if (deleteObj is ISoftDelete) - { - ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, deleteObj); - return await (await GetDbSimpleClientAsync()).UpdateAsync(deleteObj); - } - else - { - return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObj); - } - } - - public virtual async Task DeleteAsync(List deleteObjs) - { - if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) - { - deleteObjs.ForEach(e => ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e)); - return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(deleteObjs); - } - else - { - return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObjs); - } - } - - public virtual async Task DeleteAsync(Expression> whereExpression) - { - if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) - { - return await (await GetDbSimpleClientAsync()).AsUpdateable().SetColumns(nameof(ISoftDelete), true) - .Where(whereExpression).ExecuteCommandAsync() > 0; - } - else - { - return await (await GetDbSimpleClientAsync()).DeleteAsync(whereExpression); - } - } - - public virtual async Task DeleteByIdAsync(dynamic id) - { - if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) - { - var entity = await GetByIdAsync(id); - //反射赋值 - ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity); - return await UpdateAsync(entity); - } - else - { - return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(id); - } - } - - public virtual async Task DeleteByIdsAsync(dynamic[] ids) - { - if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) - { - var simpleClient = (await GetDbSimpleClientAsync()); - var entities = await simpleClient.AsQueryable().In(ids).ToListAsync(); - if (entities.Count == 0) - { - return false; - } - - // 反射赋值 - entities.ForEach(e => ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e)); - return await UpdateRangeAsync(entities); - } - else - { - return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(ids); - } - } - - public virtual async Task GetByIdAsync(dynamic id) - { - return await (await GetDbSimpleClientAsync()).GetByIdAsync(id); - } - - - public virtual async Task GetFirstAsync(Expression> whereExpression) - { - return await (await GetDbSimpleClientAsync()).GetFirstAsync(whereExpression); - } - - public virtual async Task> GetListAsync() - { - return await (await GetDbSimpleClientAsync()).GetListAsync(); - } - - public virtual async Task> GetListAsync(Expression> whereExpression) - { - return await (await GetDbSimpleClientAsync()).GetListAsync(whereExpression); - } - - public virtual async Task> GetPageListAsync(Expression> whereExpression, - int pageNum, int pageSize) - { - return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, - new PageModel() { PageIndex = pageNum, PageSize = pageSize }); - } - - public virtual async Task> GetPageListAsync(Expression> whereExpression, - int pageNum, int pageSize, - Expression>? orderByExpression = null, OrderByType orderByType = OrderByType.Asc) - { - return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, - new PageModel { PageIndex = pageNum, PageSize = pageSize }, orderByExpression, orderByType); - } - - public virtual async Task GetSingleAsync(Expression> whereExpression) - { - return await (await GetDbSimpleClientAsync()).GetSingleAsync(whereExpression); - } - - public virtual async Task InsertAsync(TEntity insertObj) - { - return await (await GetDbSimpleClientAsync()).InsertAsync(insertObj); - } - - public virtual async Task InsertOrUpdateAsync(TEntity data) - { - return await (await GetDbSimpleClientAsync()).InsertOrUpdateAsync(data); - } - - public virtual async Task InsertOrUpdateAsync(List datas) - { - return await (await GetDbSimpleClientAsync()).InsertOrUpdateAsync(datas); - } - - public virtual async Task InsertRangeAsync(List insertObjs) - { - return await (await GetDbSimpleClientAsync()).InsertRangeAsync(insertObjs); - } - - public virtual async Task InsertReturnBigIdentityAsync(TEntity insertObj) - { - return await (await GetDbSimpleClientAsync()).InsertReturnBigIdentityAsync(insertObj); - } - - public virtual async Task InsertReturnEntityAsync(TEntity insertObj) - { - return await (await GetDbSimpleClientAsync()).InsertReturnEntityAsync(insertObj); - } - - public virtual async Task InsertReturnIdentityAsync(TEntity insertObj) - { - return await (await GetDbSimpleClientAsync()).InsertReturnIdentityAsync(insertObj); - } - - public virtual async Task InsertReturnSnowflakeIdAsync(TEntity insertObj) - { - return await (await GetDbSimpleClientAsync()).InsertReturnSnowflakeIdAsync(insertObj); - } - - public virtual async Task IsAnyAsync(Expression> whereExpression) - { - return await (await GetDbSimpleClientAsync()).IsAnyAsync(whereExpression); - } - - public virtual async Task UpdateAsync(TEntity updateObj) - { - return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj); - } - - public virtual async Task UpdateAsync(Expression> columns, - Expression> whereExpression) - { - return await (await GetDbSimpleClientAsync()).UpdateAsync(columns, whereExpression); - } - - public virtual async Task UpdateRangeAsync(List updateObjs) - { - return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(updateObjs); - } - - #endregion -} - -public class SqlSugarRepository : SqlSugarRepository, ISqlSugarRepository, - IRepository where TEntity : class, IEntity, new() -{ - public SqlSugarRepository(ISugarDbContextProvider sugarDbContextProvider) : base( - sugarDbContextProvider) - { - } - - public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) - { - await DeleteByIdAsync(id); - } - - public virtual async Task DeleteManyAsync(IEnumerable ids, bool autoSave = false, - CancellationToken cancellationToken = default) - { - await DeleteByIdsAsync(ids.Select(x => (object)x).ToArray()); - } - - public virtual async Task FindAsync(TKey id, bool includeDetails = true, - CancellationToken cancellationToken = default) - { - return await GetByIdAsync(id); - } - - public virtual async Task GetAsync(TKey id, bool includeDetails = true, - CancellationToken cancellationToken = default) - { - return await GetByIdAsync(id); - } +using System.Linq.Expressions; +using NPin.Framework.Core.Helper; +using NPin.Framework.SqlSugarCore.Abstractions; +using SqlSugar; +using Volo.Abp; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Linq; + +namespace NPin.Framework.SqlSugarCore.Repositories; + +public class SqlSugarRepository : ISqlSugarRepository, IRepository + where TEntity : class, IEntity, new() +{ + public ISqlSugarClient Db => GetDbContextAsync().Result; + + public ISugarQueryable DbQueryable => GetDbContextAsync().Result.Queryable(); + + private ISugarDbContextProvider _sugarDbContextProvider; + public IAsyncQueryableExecuter AsyncExecuter { get; } + + public bool? IsChangeTrackingEnabled => false; + + public SqlSugarRepository(ISugarDbContextProvider sugarDbContextProvider) + { + _sugarDbContextProvider = sugarDbContextProvider; + } + + public virtual async Task GetDbContextAsync() + { + var db = (await _sugarDbContextProvider.GetDbContextAsync()).SqlSugarClient; + // await Console.Out.WriteLineAsync("获取的id:" + db.ContextID); + return db; + } + + public virtual async Task> GetDbSimpleClientAsync() + { + var db = await GetDbContextAsync(); + return new SimpleClient(db); + } + + #region Abp模块 + + public virtual async Task FindAsync(Expression> predicate, bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return await GetFirstAsync(predicate); + } + + public virtual async Task GetAsync(Expression> predicate, bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return await GetFirstAsync(predicate); + } + + public virtual async Task DeleteAsync(Expression> predicate, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await this.DeleteAsync(predicate); + } + + public virtual async Task DeleteDirectAsync(Expression> predicate, + CancellationToken cancellationToken = default) + { + await this.DeleteAsync(predicate); + } + + public IQueryable WithDetails() + { + throw new NotImplementedException(); + } + + public IQueryable WithDetails(params Expression>[] propertySelectors) + { + throw new NotImplementedException(); + } + + public Task> WithDetailsAsync() + { + throw new NotImplementedException(); + } + + public Task> WithDetailsAsync(params Expression>[] propertySelectors) + { + throw new NotImplementedException(); + } + + public Task> GetQueryableAsync() + { + throw new NotImplementedException(); + } + + public virtual async Task> GetListAsync(Expression> predicate, + bool includeDetails = false, CancellationToken cancellationToken = default) + { + return await GetListAsync(predicate); + } + + public virtual async Task InsertAsync(TEntity entity, bool autoSave = false, + CancellationToken cancellationToken = default) + { + return await InsertReturnEntityAsync(entity); + } + + public virtual async Task InsertManyAsync(IEnumerable entities, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await InsertRangeAsync(entities.ToList()); + } + + public virtual async Task UpdateAsync(TEntity entity, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await UpdateAsync(entity); + return entity; + } + + public virtual async Task UpdateManyAsync(IEnumerable entities, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await UpdateRangeAsync(entities.ToList()); + } + + public virtual async Task DeleteAsync(TEntity entity, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await DeleteAsync(entity); + } + + public virtual async Task DeleteManyAsync(IEnumerable entities, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await DeleteAsync(entities.ToList()); + } + + public virtual async Task> GetListAsync(bool includeDetails = false, + CancellationToken cancellationToken = default) + { + return await GetListAsync(); + } + + public virtual async Task GetCountAsync(CancellationToken cancellationToken = default) + { + return await this.CountAsync(); + } + + public virtual async Task> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, + bool includeDetails = false, CancellationToken cancellationToken = default) + { + return await GetPageListAsync(_ => true, skipCount, maxResultCount); + } + + #endregion + + #region 内置DB快捷操作 + + public virtual async Task> AsDeleteable() + { + return (await GetDbSimpleClientAsync()).AsDeleteable(); + } + + public virtual async Task> AsInsertable(List insertObjs) + { + return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs); + } + + public virtual async Task> AsInsertable(TEntity insertObj) + { + return (await GetDbSimpleClientAsync()).AsInsertable(insertObj); + } + + public virtual async Task> AsInsertable(TEntity[] insertObjs) + { + return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs); + } + + public virtual async Task> AsQueryable() + { + return (await GetDbSimpleClientAsync()).AsQueryable(); + } + + public virtual async Task AsSugarClient() + { + return (await GetDbSimpleClientAsync()).AsSugarClient(); + } + + public virtual async Task AsTenant() + { + return (await GetDbSimpleClientAsync()).AsTenant(); + } + + public virtual async Task> AsUpdateable(List updateObjs) + { + return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs); + } + + public virtual async Task> AsUpdateable(TEntity updateObj) + { + return (await GetDbSimpleClientAsync()).AsUpdateable(updateObj); + } + + public virtual async Task> AsUpdateable() + { + return (await GetDbSimpleClientAsync()).AsUpdateable(); + } + + public virtual async Task> AsUpdateable(TEntity[] updateObjs) + { + return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs); + } + + #endregion + + #region SimpleClient模块 + + public virtual async Task CountAsync(Expression> whereExpression) + { + return await (await GetDbSimpleClientAsync()).CountAsync(whereExpression); + } + + public virtual async Task DeleteAsync(TEntity deleteObj) + { + if (deleteObj is ISoftDelete) + { + ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, deleteObj); + return await (await GetDbSimpleClientAsync()).UpdateAsync(deleteObj); + } + else + { + return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObj); + } + } + + public virtual async Task DeleteAsync(List deleteObjs) + { + if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) + { + deleteObjs.ForEach(e => ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e)); + return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(deleteObjs); + } + else + { + return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObjs); + } + } + + public virtual async Task DeleteAsync(Expression> whereExpression) + { + if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) + { + return await (await GetDbSimpleClientAsync()).AsUpdateable().SetColumns(nameof(ISoftDelete), true) + .Where(whereExpression).ExecuteCommandAsync() > 0; + } + else + { + return await (await GetDbSimpleClientAsync()).DeleteAsync(whereExpression); + } + } + + public virtual async Task DeleteByIdAsync(dynamic id) + { + if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) + { + var entity = await GetByIdAsync(id); + //反射赋值 + ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity); + return await UpdateAsync(entity); + } + else + { + return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(id); + } + } + + public virtual async Task DeleteByIdsAsync(dynamic[] ids) + { + if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) + { + var simpleClient = (await GetDbSimpleClientAsync()); + var entities = await simpleClient.AsQueryable().In(ids).ToListAsync(); + if (entities.Count == 0) + { + return false; + } + + // 反射赋值 + entities.ForEach(e => ReflectHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e)); + return await UpdateRangeAsync(entities); + } + else + { + return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(ids); + } + } + + public virtual async Task GetByIdAsync(dynamic id) + { + return await (await GetDbSimpleClientAsync()).GetByIdAsync(id); + } + + + public virtual async Task GetFirstAsync(Expression> whereExpression) + { + return await (await GetDbSimpleClientAsync()).GetFirstAsync(whereExpression); + } + + public virtual async Task> GetListAsync() + { + return await (await GetDbSimpleClientAsync()).GetListAsync(); + } + + public virtual async Task> GetListAsync(Expression> whereExpression) + { + return await (await GetDbSimpleClientAsync()).GetListAsync(whereExpression); + } + + public virtual async Task> GetPageListAsync(Expression> whereExpression, + int pageNum, int pageSize) + { + return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, + new PageModel() { PageIndex = pageNum, PageSize = pageSize }); + } + + public virtual async Task> GetPageListAsync(Expression> whereExpression, + int pageNum, int pageSize, + Expression>? orderByExpression = null, OrderByType orderByType = OrderByType.Asc) + { + return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, + new PageModel { PageIndex = pageNum, PageSize = pageSize }, orderByExpression, orderByType); + } + + public virtual async Task GetSingleAsync(Expression> whereExpression) + { + return await (await GetDbSimpleClientAsync()).GetSingleAsync(whereExpression); + } + + public virtual async Task InsertAsync(TEntity insertObj) + { + return await (await GetDbSimpleClientAsync()).InsertAsync(insertObj); + } + + public virtual async Task InsertOrUpdateAsync(TEntity data) + { + return await (await GetDbSimpleClientAsync()).InsertOrUpdateAsync(data); + } + + public virtual async Task InsertOrUpdateAsync(List datas) + { + return await (await GetDbSimpleClientAsync()).InsertOrUpdateAsync(datas); + } + + public virtual async Task InsertRangeAsync(List insertObjs) + { + return await (await GetDbSimpleClientAsync()).InsertRangeAsync(insertObjs); + } + + public virtual async Task InsertReturnBigIdentityAsync(TEntity insertObj) + { + return await (await GetDbSimpleClientAsync()).InsertReturnBigIdentityAsync(insertObj); + } + + public virtual async Task InsertReturnEntityAsync(TEntity insertObj) + { + return await (await GetDbSimpleClientAsync()).InsertReturnEntityAsync(insertObj); + } + + public virtual async Task InsertReturnIdentityAsync(TEntity insertObj) + { + return await (await GetDbSimpleClientAsync()).InsertReturnIdentityAsync(insertObj); + } + + public virtual async Task InsertReturnSnowflakeIdAsync(TEntity insertObj) + { + return await (await GetDbSimpleClientAsync()).InsertReturnSnowflakeIdAsync(insertObj); + } + + public virtual async Task IsAnyAsync(Expression> whereExpression) + { + return await (await GetDbSimpleClientAsync()).IsAnyAsync(whereExpression); + } + + public virtual async Task UpdateAsync(TEntity updateObj) + { + return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj); + } + + public virtual async Task UpdateAsync(Expression> columns, + Expression> whereExpression) + { + return await (await GetDbSimpleClientAsync()).UpdateAsync(columns, whereExpression); + } + + public virtual async Task UpdateRangeAsync(List updateObjs) + { + return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(updateObjs); + } + + #endregion +} + +public class SqlSugarRepository : SqlSugarRepository, ISqlSugarRepository, + IRepository where TEntity : class, IEntity, new() +{ + public SqlSugarRepository(ISugarDbContextProvider sugarDbContextProvider) : base( + sugarDbContextProvider) + { + } + + public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) + { + await DeleteByIdAsync(id); + } + + public virtual async Task DeleteManyAsync(IEnumerable ids, bool autoSave = false, + CancellationToken cancellationToken = default) + { + await DeleteByIdsAsync(ids.Select(x => (object)x).ToArray()); + } + + public virtual async Task FindAsync(TKey id, bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return await GetByIdAsync(id); + } + + public virtual async Task GetAsync(TKey id, bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return await GetByIdAsync(id); + } } \ No newline at end of file diff --git a/framework/NPin.Framework.SqlSugarCore/SqlSugarDbConnectionCreator.cs b/framework/NPin.Framework.SqlSugarCore/SqlSugarDbConnectionCreator.cs index a88b6a5..2a95709 100644 --- a/framework/NPin.Framework.SqlSugarCore/SqlSugarDbConnectionCreator.cs +++ b/framework/NPin.Framework.SqlSugarCore/SqlSugarDbConnectionCreator.cs @@ -1,117 +1,124 @@ -using System.Reflection; -using Microsoft.Extensions.Options; -using NPin.Framework.SqlSugarCore.Abstractions; -using SqlSugar; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; - -namespace NPin.Framework.SqlSugarCore; - -public class SqlSugarDbConnectionCreator : ISqlSugarDbConnectionCreator, ITransientDependency -{ - [DisablePropertyInjection] public Action OnSqlSugarClientConfig { get; set; } - - [DisablePropertyInjection] public Action DataExecuted { get; set; } - - [DisablePropertyInjection] public Action DataExecuting { get; set; } - - [DisablePropertyInjection] public Action OnLogExecuting { get; set; } - - [DisablePropertyInjection] public Action OnLogExecuted { get; set; } - - [DisablePropertyInjection] public Action EntityService { get; set; } - - [DisablePropertyInjection] public Action EntityNameService { get; set; } - - public DbConnOptions Options { get; } - - public SqlSugarDbConnectionCreator(IOptions options) - { - Options = options.Value; - } - - public void SetDbAop(ISqlSugarClient currentDb) - { - currentDb.Aop.OnLogExecuting = this.OnLogExecuting; - currentDb.Aop.OnLogExecuted = this.OnLogExecuted; - currentDb.Aop.DataExecuting = this.DataExecuting; - currentDb.Aop.DataExecuted = this.DataExecuted; - OnSqlSugarClientConfig(currentDb); - } - - public ConnectionConfig Build(Action? action = null) - { - var dbConnOptions = Options; - - #region 组装Options - - if (dbConnOptions.DbType is null) - { - throw new ArgumentException("DbType配置为空"); - } - - // 读写分离 slave模式 - var slaveConfigs = new List(); - if (dbConnOptions.EnabledReadWrite) - { - if (dbConnOptions.ReadUrl is null) - { - throw new ArgumentException("读写分离开启,但读库配置为空"); - } - - var readConn = dbConnOptions.ReadUrl; - readConn.ForEach(s => - { - // 如果是动态分库,连接串不能写死,需要动态添加,所以此处只配置共享库的连接 - slaveConfigs.Add(new SlaveConnectionConfig { ConnectionString = s }); - }); - } - - #endregion - - #region 组装连接配置 - - var connectionConfig = new ConnectionConfig - { - ConfigId = ConnectionStrings.DefaultConnectionStringName, - DbType = dbConnOptions.DbType ?? DbType.Sqlite, - ConnectionString = dbConnOptions.Url, - IsAutoCloseConnection = true, - SlaveConnectionConfigs = slaveConfigs, - // CodeFirst 非空值判断 - ConfigureExternalServices = new ConfigureExternalServices - { - EntityService = (c, p) => - { - if (new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable) - { - p.IsNullable = true; - } - - EntityService(c, p); - }, - EntityNameService = (t, e) => - { - EntityNameService(t, e); - } - }, - // Aop - AopEvents = new AopEvents - { - DataExecuted = DataExecuted, - DataExecuting = DataExecuting, - OnLogExecuted = OnLogExecuted, - OnLogExecuting = OnLogExecuting - } - }; - - if (action is not null) - { - action.Invoke(connectionConfig); - } - - #endregion - - return connectionConfig; - } +using System.Reflection; +using Microsoft.Extensions.Options; +using NPin.Framework.SqlSugarCore.Abstractions; +using SqlSugar; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.SqlSugarCore; + +public class SqlSugarDbConnectionCreator : ISqlSugarDbConnectionCreator, ITransientDependency +{ + [DisablePropertyInjection] public Action OnSqlSugarClientConfig { get; set; } + + [DisablePropertyInjection] public Action DataExecuted { get; set; } + + [DisablePropertyInjection] public Action DataExecuting { get; set; } + + [DisablePropertyInjection] public Action OnLogExecuting { get; set; } + + [DisablePropertyInjection] public Action OnLogExecuted { get; set; } + + [DisablePropertyInjection] public Action EntityService { get; set; } + + [DisablePropertyInjection] public Action EntityNameService { get; set; } + + public DbConnOptions Options { get; } + + public SqlSugarDbConnectionCreator(IOptions options) + { + Options = options.Value; + } + + public void SetDbAop(ISqlSugarClient currentDb) + { + currentDb.Aop.OnLogExecuting = this.OnLogExecuting; + currentDb.Aop.OnLogExecuted = this.OnLogExecuted; + currentDb.Aop.DataExecuting = this.DataExecuting; + currentDb.Aop.DataExecuted = this.DataExecuted; + OnSqlSugarClientConfig(currentDb); + } + + public ConnectionConfig Build(Action? action = null) + { + var dbConnOptions = Options; + + #region 组装Options + + if (dbConnOptions.DbType is null) + { + throw new ArgumentException("DbType配置为空"); + } + + // 读写分离 slave模式 + var slaveConfigs = new List(); + if (dbConnOptions.EnabledReadWrite) + { + if (dbConnOptions.ReadUrl is null) + { + throw new ArgumentException("读写分离开启,但读库配置为空"); + } + + var readConn = dbConnOptions.ReadUrl; + readConn.ForEach(s => + { + // 如果是动态分库,连接串不能写死,需要动态添加,所以此处只配置共享库的连接 + slaveConfigs.Add(new SlaveConnectionConfig { ConnectionString = s }); + }); + } + + #endregion + + #region 组装连接配置 + + var connectionConfig = new ConnectionConfig + { + ConfigId = ConnectionStrings.DefaultConnectionStringName, + DbType = dbConnOptions.DbType ?? DbType.Sqlite, + ConnectionString = dbConnOptions.Url, + IsAutoCloseConnection = true, + SlaveConnectionConfigs = slaveConfigs, + LanguageType = LanguageType.Chinese, + MoreSettings = new ConnMoreSettings + { + SqliteCodeFirstEnableDescription = true, + PgSqlIsAutoToLower = true, + PgSqlIsAutoToLowerCodeFirst = true, + }, + // CodeFirst 非空值判断 + ConfigureExternalServices = new ConfigureExternalServices + { + EntityService = (c, p) => + { + if (new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable) + { + p.IsNullable = true; + } + + EntityService(c, p); + }, + EntityNameService = (t, e) => + { + EntityNameService(t, e); + } + }, + // Aop + AopEvents = new AopEvents + { + DataExecuted = DataExecuted, + DataExecuting = DataExecuting, + OnLogExecuted = OnLogExecuted, + OnLogExecuting = OnLogExecuting + } + }; + + if (action is not null) + { + action.Invoke(connectionConfig); + } + + #endregion + + return connectionConfig; + } } \ No newline at end of file diff --git a/framework/NPin.Framework.SqlSugarCore/SqlSugarDbContext.cs b/framework/NPin.Framework.SqlSugarCore/SqlSugarDbContext.cs index f411de9..ee79f01 100644 --- a/framework/NPin.Framework.SqlSugarCore/SqlSugarDbContext.cs +++ b/framework/NPin.Framework.SqlSugarCore/SqlSugarDbContext.cs @@ -1,269 +1,306 @@ -using System.Reflection; -using System.Text; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using NPin.Framework.SqlSugarCore.Abstractions; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Domain.Entities.Events; -using Volo.Abp.Guids; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Users; - -namespace NPin.Framework.SqlSugarCore; - -public class SqlSugarDbContext : ISqlSugarDbContext -{ - private IAbpLazyServiceProvider LazyServiceProvider { get; } - - public ISqlSugarClient SqlSugarClient { get; private set; } - public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService>().Value; - public ICurrentUser CurrentUser => LazyServiceProvider.GetRequiredService(); - public ICurrentTenant? CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); - public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); - - private IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetRequiredService(); - - protected ILoggerFactory Logger => LazyServiceProvider.LazyGetRequiredService(); - protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled() ?? false; - protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled() ?? false; - - public IEntityChangeEventHelper EntityChangeEventHelper => - LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance); - - public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient) - { - SqlSugarClient = sqlSugarClient; - } - - public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider) - { - LazyServiceProvider = lazyServiceProvider; - var connectionCreator = LazyServiceProvider.LazyGetRequiredService(); - connectionCreator.OnSqlSugarClientConfig = OnSqlSugarClientConfig; - connectionCreator.EntityService = EntityService; - connectionCreator.EntityNameService = EntityNameService; - connectionCreator.DataExecuting = DataExecuting; - connectionCreator.DataExecuted = DataExecuted; - connectionCreator.OnLogExecuting = OnLogExecuting; - connectionCreator.OnLogExecuted = OnLogExecuted; - SqlSugarClient = new SqlSugarClient(connectionCreator.Build()); - connectionCreator.SetDbAop(SqlSugarClient); - } - - /// - /// 上下文对象扩展 - /// - /// - protected virtual void OnSqlSugarClientConfig(ISqlSugarClient sqlSugarClient) - { - //需自定义扩展 - if (IsSoftDeleteFilterEnabled) - { - sqlSugarClient.QueryFilter.AddTableFilter(u => u.IsDeleted == false); - } - - if (IsMultiTenantFilterEnabled) - { - sqlSugarClient.QueryFilter.AddTableFilter(u => u.TenantId == GuidGenerator.Create()); - } - - // 自定义其它Filter - CustomDataFilter(sqlSugarClient); - } - - protected virtual void CustomDataFilter(ISqlSugarClient sqlSugarClient) - { - } - - protected virtual void DataExecuted(object oldValue, DataAfterModel entityInfo) - { - } - - protected virtual void DataExecuting(object? oldValue, DataFilterModel entityInfo) - { - // 审计日志 - switch (entityInfo.OperationType) - { - case DataFilterType.UpdateByObject: - if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModificationTime))) - { - if (!DateTime.MinValue.Equals(oldValue)) - { - entityInfo.SetValue(DateTime.Now); - } - } - - if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId))) - { - if (CurrentUser.Id != null) - { - entityInfo.SetValue(CurrentUser.Id); - } - } - - break; - case DataFilterType.InsertByObject: - if (entityInfo.PropertyName.Equals(nameof(IEntity.Id))) - { - //主键为空或者为默认最小值 - if (Guid.Empty.Equals(oldValue)) - { - entityInfo.SetValue(GuidGenerator.Create()); - } - } - - if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime))) - { - //为空或者为默认最小值 - if (oldValue is null || DateTime.MinValue.Equals(oldValue)) - { - entityInfo.SetValue(DateTime.Now); - } - } - - if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId))) - { - if (CurrentUser.Id != null) - { - entityInfo.SetValue(CurrentUser.Id); - } - } - - //插入时,需要租户id,先预留 - if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId))) - { - if (CurrentTenant is not null) - { - entityInfo.SetValue(CurrentTenant.Id); - } - } - - break; - } - - - //领域事件 - switch (entityInfo.OperationType) - { - case DataFilterType.InsertByObject: - if (entityInfo.PropertyName == nameof(IEntity.Id)) - { - EntityChangeEventHelper.PublishEntityCreatedEvent(entityInfo.EntityValue); - } - - break; - case DataFilterType.UpdateByObject: - if (entityInfo.PropertyName == nameof(IEntity.Id)) - { - //软删除,发布的是删除事件 - if (entityInfo.EntityValue is ISoftDelete softDelete) - { - if (softDelete.IsDeleted) - { - EntityChangeEventHelper.PublishEntityDeletedEvent(entityInfo.EntityValue); - } - } - else - { - EntityChangeEventHelper.PublishEntityUpdatedEvent(entityInfo.EntityValue); - } - } - - break; - case DataFilterType.DeleteByObject: - if (entityInfo.PropertyName == nameof(IEntity.Id)) - { - EntityChangeEventHelper.PublishEntityDeletedEvent(entityInfo.EntityValue); - } - - break; - } - } - - protected virtual void OnLogExecuting(string sql, SugarParameter[] pars) - { - if (Options.EnabledSqlLog) - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine(); - sb.AppendLine("==========NPin-SQL=========="); - sb.AppendLine(UtilMethods.GetSqlString(DbType.SqlServer, sql, pars)); - sb.AppendLine("============================"); - Logger.CreateLogger().LogDebug(sb.ToString()); - } - } - - protected virtual void OnLogExecuted(string sql, SugarParameter[] pars) - { - } - - /// - /// 实体配置 - /// 自动主键 - /// 自动Ignore关联配置(导航) - /// 开启下划线 - /// - /// - /// - protected virtual void EntityService(PropertyInfo property, EntityColumnInfo column) - { - if (property.PropertyType == typeof(ExtraPropertyDictionary)) - { - column.IsIgnore = true; - } - - if (property.Name == nameof(Entity.Id)) - { - column.IsPrimarykey = true; - } - - column.DbColumnName = UtilMethods.ToUnderLine(column.DbColumnName); - } - - /// - /// EntityName 配置 - /// 开启下划线 - /// - /// - /// - protected virtual void EntityNameService(Type type, EntityInfo entity) - { - // 开启下划线 - entity.DbTableName = UtilMethods.ToUnderLine(entity.DbTableName); - } - - public void Backup() - { - string directoryName = "database_backup"; - string fileName = $"{SqlSugarClient.Ado.Connection.Database}_" + DateTime.Now.ToString("yyyyMMdd_HHmmss"); - if (!Directory.Exists(directoryName)) - { - Directory.CreateDirectory(directoryName); - } - - switch (Options.DbType) - { - case DbType.MySql: - // mysql 只支持.net core - SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, - $"{Path.Combine(directoryName, fileName)}.sql"); - break; - case DbType.Sqlite: - // sqlite 只支持.net core - SqlSugarClient.DbMaintenance.BackupDataBase(null, $"{fileName}.db"); - break; - case DbType.SqlServer: - // 第一个参数库名 - SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, - $"{Path.Combine(directoryName, fileName)}.bak"); - break; - default: - throw new NotImplementedException("其他数据库备份未实现"); - } - } +using System.Reflection; +using System.Text; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using NPin.Framework.SqlSugarCore.Abstractions; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Users; + +namespace NPin.Framework.SqlSugarCore; + +public class SqlSugarDbContext : ISqlSugarDbContext +{ + private IAbpLazyServiceProvider LazyServiceProvider { get; } + + public ISqlSugarClient SqlSugarClient { get; private set; } + public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService>().Value; + public ICurrentUser CurrentUser => LazyServiceProvider.GetRequiredService(); + public ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService(); + public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService(); + + private IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetRequiredService(); + + protected ILoggerFactory Logger => LazyServiceProvider.LazyGetRequiredService(); + protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled() ?? false; + protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled() ?? false; + + public IEntityChangeEventHelper EntityChangeEventHelper => + LazyServiceProvider.LazyGetService(NullEntityChangeEventHelper.Instance); + + public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient) + { + SqlSugarClient = sqlSugarClient; + } + + public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider) + { + LazyServiceProvider = lazyServiceProvider; + var connectionCreator = LazyServiceProvider.LazyGetRequiredService(); + connectionCreator.OnSqlSugarClientConfig = OnSqlSugarClientConfig; + connectionCreator.EntityService = EntityService; + connectionCreator.EntityNameService = EntityNameService; + connectionCreator.DataExecuting = DataExecuting; + connectionCreator.DataExecuted = DataExecuted; + connectionCreator.OnLogExecuting = OnLogExecuting; + connectionCreator.OnLogExecuted = OnLogExecuted; + var connStr = GetCurrentConnectionString(); + + SqlSugarClient = new SqlSugarClient(connectionCreator.Build(action: opt => + { + opt.ConnectionString = connStr; + })); + connectionCreator.SetDbAop(SqlSugarClient); + } + + /// + /// db切换多库支持 + /// + /// + protected virtual string GetCurrentConnectionString() + { + var connectionStringResolver = LazyServiceProvider.LazyGetRequiredService(); + var connectionString = connectionStringResolver.ResolveAsync().Result; + + //没有检测到使用多租户功能,默认使用默认库即可 + if (string.IsNullOrWhiteSpace(connectionString)) + { + Volo.Abp.Check.NotNull(Options.Url, "租户默认库Default未找到"); + connectionString = Options.Url; + } + + //如果当前租户是主库,单独使用主要库 + if (CurrentTenant.Name == DbConnOptions.MasterTenantName) + { + var conStrOrNull = Options.GetMasterSaasMultiTenancy(); + Volo.Abp.Check.NotNull(conStrOrNull, "租户主库Master未找到"); + connectionString = conStrOrNull.Url; + } + + return connectionString!; + } + + /// + /// 上下文对象扩展 + /// + /// + protected virtual void OnSqlSugarClientConfig(ISqlSugarClient sqlSugarClient) + { + //需自定义扩展 + if (IsSoftDeleteFilterEnabled) + { + sqlSugarClient.QueryFilter.AddTableFilter(u => u.IsDeleted == false); + } + + if (IsMultiTenantFilterEnabled) + { + sqlSugarClient.QueryFilter.AddTableFilter(u => u.TenantId == CurrentTenant.Id); + } + + // 自定义其它Filter + CustomDataFilter(sqlSugarClient); + } + + protected virtual void CustomDataFilter(ISqlSugarClient sqlSugarClient) + { + } + + protected virtual void DataExecuted(object oldValue, DataAfterModel entityInfo) + { + } + + protected virtual void DataExecuting(object? oldValue, DataFilterModel entityInfo) + { + // 审计日志 + switch (entityInfo.OperationType) + { + case DataFilterType.UpdateByObject: + if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModificationTime))) + { + if (!DateTime.MinValue.Equals(oldValue)) + { + entityInfo.SetValue(DateTime.Now); + } + } + + if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId))) + { + if (CurrentUser.Id != null) + { + entityInfo.SetValue(CurrentUser.Id); + } + } + + break; + case DataFilterType.InsertByObject: + if (entityInfo.PropertyName.Equals(nameof(IEntity.Id))) + { + //主键为空或者为默认最小值 + if (Guid.Empty.Equals(oldValue)) + { + entityInfo.SetValue(GuidGenerator.Create()); + } + } + + if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime))) + { + //为空或者为默认最小值 + if (oldValue is null || DateTime.MinValue.Equals(oldValue)) + { + entityInfo.SetValue(DateTime.Now); + } + } + + if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId))) + { + if (CurrentUser.Id != null) + { + entityInfo.SetValue(CurrentUser.Id); + } + } + + //插入时,需要租户id,先预留 + if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId))) + { + if (CurrentTenant is not null) + { + entityInfo.SetValue(CurrentTenant.Id); + } + } + + break; + } + + + //领域事件 + switch (entityInfo.OperationType) + { + case DataFilterType.InsertByObject: + if (entityInfo.PropertyName == nameof(IEntity.Id)) + { + EntityChangeEventHelper.PublishEntityCreatedEvent(entityInfo.EntityValue); + } + + break; + case DataFilterType.UpdateByObject: + if (entityInfo.PropertyName == nameof(IEntity.Id)) + { + //软删除,发布的是删除事件 + if (entityInfo.EntityValue is ISoftDelete softDelete) + { + if (softDelete.IsDeleted) + { + EntityChangeEventHelper.PublishEntityDeletedEvent(entityInfo.EntityValue); + } + } + else + { + EntityChangeEventHelper.PublishEntityUpdatedEvent(entityInfo.EntityValue); + } + } + + break; + case DataFilterType.DeleteByObject: + if (entityInfo.PropertyName == nameof(IEntity.Id)) + { + EntityChangeEventHelper.PublishEntityDeletedEvent(entityInfo.EntityValue); + } + + break; + } + } + + protected virtual void OnLogExecuting(string sql, SugarParameter[] pars) + { + if (Options.EnabledSqlLog) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine(); + sb.AppendLine("==========NPin-SQL=========="); + sb.AppendLine(UtilMethods.GetSqlString(DbType.SqlServer, sql, pars)); + sb.AppendLine("============================"); + Logger.CreateLogger().LogDebug(sb.ToString()); + } + } + + protected virtual void OnLogExecuted(string sql, SugarParameter[] pars) + { + if (Options.EnabledSqlLog) + { + var sqllog = $"=========NPin-SQL耗时{SqlSugarClient.Ado.SqlExecutionTime.TotalMilliseconds}毫秒====="; + Logger.CreateLogger().LogDebug(sqllog); + } + } + + /// + /// 实体配置 + /// 自动主键 + /// 自动Ignore关联配置(导航) + /// 开启下划线 + /// + /// + /// + protected virtual void EntityService(PropertyInfo property, EntityColumnInfo column) + { + if (property.PropertyType == typeof(ExtraPropertyDictionary)) + { + column.IsIgnore = true; + } + + if (property.Name == nameof(Entity.Id)) + { + column.IsPrimarykey = true; + } + + column.DbColumnName = UtilMethods.ToUnderLine(column.DbColumnName); + } + + /// + /// EntityName 配置 + /// 开启下划线 + /// + /// + /// + protected virtual void EntityNameService(Type type, EntityInfo entity) + { + // 开启下划线 + entity.DbTableName = UtilMethods.ToUnderLine(entity.DbTableName); + } + + public void Backup() + { + string directoryName = "database_backup"; + string fileName = $"{SqlSugarClient.Ado.Connection.Database}_" + DateTime.Now.ToString("yyyyMMdd_HHmmss"); + if (!Directory.Exists(directoryName)) + { + Directory.CreateDirectory(directoryName); + } + + switch (Options.DbType) + { + case DbType.MySql: + // mysql 只支持.net core + SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, + $"{Path.Combine(directoryName, fileName)}.sql"); + break; + case DbType.Sqlite: + // sqlite 只支持.net core + SqlSugarClient.DbMaintenance.BackupDataBase(null, $"{fileName}.db"); + break; + case DbType.SqlServer: + // 第一个参数库名 + SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, + $"{Path.Combine(directoryName, fileName)}.bak"); + break; + default: + throw new NotImplementedException("其他数据库备份未实现"); + } + } } \ No newline at end of file diff --git a/framework/NPin.Framework.SqlSugarCore/Uow/UnitOfWorkSqlSugarDbContextProvider.cs b/framework/NPin.Framework.SqlSugarCore/Uow/UnitOfWorkSqlSugarDbContextProvider.cs index e227fb3..2a463c7 100644 --- a/framework/NPin.Framework.SqlSugarCore/Uow/UnitOfWorkSqlSugarDbContextProvider.cs +++ b/framework/NPin.Framework.SqlSugarCore/Uow/UnitOfWorkSqlSugarDbContextProvider.cs @@ -1,135 +1,140 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using NPin.Framework.SqlSugarCore.Abstractions; -using Volo.Abp.Data; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Threading; -using Volo.Abp.Uow; - -namespace NPin.Framework.SqlSugarCore.Uow; - -public class UnitOfWorkSqlSugarDbContextProvider : ISugarDbContextProvider - where TDbContext : ISqlSugarDbContext -{ - private readonly ISqlSugarDbConnectionCreator _dbConnectionCreator; - private ILogger> Logger { get; set; } - private IServiceProvider ServiceProvider { get; set; } - - private static AsyncLocalDbContextAccessor ContextInstance => AsyncLocalDbContextAccessor.Instance; - protected readonly IUnitOfWorkManager UnitOfWorkManager; - protected readonly IConnectionStringResolver ConnectionStringResolver; - protected readonly ICancellationTokenProvider CancellationTokenProvider; - protected readonly ICurrentTenant CurrentTenant; - - public UnitOfWorkSqlSugarDbContextProvider( - IUnitOfWorkManager unitOfWorkManager, - IConnectionStringResolver connectionStringResolver, - ICancellationTokenProvider cancellationTokenProvider, - ICurrentTenant currentTenant, - ISqlSugarDbConnectionCreator dbConnectionCreator - ) - { - UnitOfWorkManager = unitOfWorkManager; - ConnectionStringResolver = connectionStringResolver; - CancellationTokenProvider = cancellationTokenProvider; - CurrentTenant = currentTenant; - Logger = NullLogger>.Instance; - _dbConnectionCreator = dbConnectionCreator; - } - - public virtual async Task GetDbContextAsync() - { - var connectionStringName = ConnectionStrings.DefaultConnectionStringName; - - // 获取当前的连接字符串,未开启多租户时为空 - var connectionString = await ResolveConnectionStringAsync(connectionStringName); - var dbContextKey = $"{GetType().FullName}_{connectionString}"; - - var unitOfWork = UnitOfWorkManager.Current; - if (unitOfWork == null || !unitOfWork.Options.IsTransactional) - { - // set if is null - ContextInstance.Current ??= (TDbContext)ServiceProvider.GetRequiredService(); - - var dbContext = (TDbContext)ContextInstance.Current; - // 提高体验,取消uow的强制性 - // 若不启用uow,创建新db,不开启事务 - return dbContext; - } - - // 尝试当前工作单元获取db - var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey); - if (databaseApi == null) - { - databaseApi = - new SqlSugarDatabaseApi(CreateDbContextAsync(unitOfWork, connectionStringName, connectionString) - .Result); - unitOfWork.AddDatabaseApi(dbContextKey, databaseApi); - } - - return (TDbContext)((SqlSugarDatabaseApi)databaseApi).DbContext; - } - - /// - /// 解析连接字符串 - /// - /// - /// - protected virtual async Task ResolveConnectionStringAsync(string connectionStringName) - { - if (typeof(TDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false)) - { - using (CurrentTenant.Change(null)) - { - return await ConnectionStringResolver.ResolveAsync(connectionStringName); - } - } - - return await ConnectionStringResolver.ResolveAsync(connectionStringName); - } - - protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork, string connectionStringName, - string connectionString) - { - var creationContext = new SqlSugarDbContextCreationContext(connectionStringName, connectionString); - //将连接key进行传值 - using (SqlSugarDbContextCreationContext.Use(creationContext)) - { - var dbContext = await CreateDbContextAsync(unitOfWork); - return dbContext; - } - } - - protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork) - { - return unitOfWork.Options.IsTransactional - ? await CreateDbContextWithTransactionAsync(unitOfWork) - : unitOfWork.ServiceProvider.GetRequiredService(); - } - - protected virtual async Task CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork) - { - //事务key - var transactionApiKey = $"SqlSugarCore_{SqlSugarDbContextCreationContext.Current.ConnectionString}"; - - //尝试查找事务 - var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as SqlSugarTransactionApi; - - //该db还没有进行开启事务 - if (activeTransaction == null) - { - //获取到db添加事务即可 - var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); - var transaction = new SqlSugarTransactionApi( - dbContext - ); - unitOfWork.AddTransactionApi(transactionApiKey, transaction); - - // await dbContext.SqlSugarClient.Ado.BeginTranAsync(); - return dbContext; - } - - return (TDbContext)activeTransaction.GetDbContext(); - } +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using NPin.Framework.SqlSugarCore.Abstractions; +using Volo.Abp.Data; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; +using Volo.Abp.Uow; + +namespace NPin.Framework.SqlSugarCore.Uow; + +public class UnitOfWorkSqlSugarDbContextProvider : ISugarDbContextProvider + where TDbContext : ISqlSugarDbContext +{ + private readonly ISqlSugarDbConnectionCreator _dbConnectionCreator; + private ILogger> Logger { get; set; } + public IServiceProvider ServiceProvider { get; set; } + + private static AsyncLocalDbContextAccessor ContextInstance => AsyncLocalDbContextAccessor.Instance; + protected readonly IUnitOfWorkManager UnitOfWorkManager; + protected readonly IConnectionStringResolver ConnectionStringResolver; + protected readonly ICancellationTokenProvider CancellationTokenProvider; + protected readonly ICurrentTenant CurrentTenant; + + public UnitOfWorkSqlSugarDbContextProvider( + IUnitOfWorkManager unitOfWorkManager, + IConnectionStringResolver connectionStringResolver, + ICancellationTokenProvider cancellationTokenProvider, + ICurrentTenant currentTenant, + ISqlSugarDbConnectionCreator dbConnectionCreator + ) + { + UnitOfWorkManager = unitOfWorkManager; + ConnectionStringResolver = connectionStringResolver; + CancellationTokenProvider = cancellationTokenProvider; + CurrentTenant = currentTenant; + Logger = NullLogger>.Instance; + _dbConnectionCreator = dbConnectionCreator; + } + + public virtual async Task GetDbContextAsync() + { + var connectionStringName = ConnectionStrings.DefaultConnectionStringName; + + // 获取当前的连接字符串,未开启多租户时为空 + var connectionString = await ResolveConnectionStringAsync(connectionStringName); + var dbContextKey = $"{GetType().FullName}_{connectionString}"; + + var unitOfWork = UnitOfWorkManager.Current; + if (unitOfWork == null || !unitOfWork.Options.IsTransactional) + { + // set if is null + if (ContextInstance.Current is null) + { + ContextInstance.Current = (TDbContext)ServiceProvider.GetRequiredService(); + } + + var dbContext = (TDbContext)ContextInstance.Current; + // 提高体验,取消uow的强制性 + // 若不启用uow,创建新db,不开启事务 + return dbContext; + } + + // 尝试当前工作单元获取db + var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey); + if (databaseApi == null) + { + // db根据连接字符串来创建 + databaseApi = new SqlSugarDatabaseApi( + CreateDbContextAsync(unitOfWork, connectionStringName, connectionString).Result + ); + // 创建的db加入到当前工作单元中 + unitOfWork.AddDatabaseApi(dbContextKey, databaseApi); + } + + return (TDbContext)((SqlSugarDatabaseApi)databaseApi).DbContext; + } + + /// + /// 解析连接字符串 + /// + /// + /// + protected virtual async Task ResolveConnectionStringAsync(string connectionStringName) + { + if (typeof(TDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false)) + { + using (CurrentTenant.Change(null)) + { + return await ConnectionStringResolver.ResolveAsync(connectionStringName); + } + } + + return await ConnectionStringResolver.ResolveAsync(connectionStringName); + } + + protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork, string connectionStringName, + string connectionString) + { + var creationContext = new SqlSugarDbContextCreationContext(connectionStringName, connectionString); + //将连接key进行传值 + using (SqlSugarDbContextCreationContext.Use(creationContext)) + { + var dbContext = await CreateDbContextAsync(unitOfWork); + return dbContext; + } + } + + protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork) + { + return unitOfWork.Options.IsTransactional + ? await CreateDbContextWithTransactionAsync(unitOfWork) + : unitOfWork.ServiceProvider.GetRequiredService(); + } + + protected virtual async Task CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork) + { + //事务key + var transactionApiKey = $"SqlSugarCore_{SqlSugarDbContextCreationContext.Current.ConnectionString}"; + + //尝试查找事务 + var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as SqlSugarTransactionApi; + + //该db还没有进行开启事务 + if (activeTransaction == null) + { + //获取到db添加事务即可 + var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); + var transaction = new SqlSugarTransactionApi( + dbContext + ); + unitOfWork.AddTransactionApi(transactionApiKey, transaction); + + await dbContext.SqlSugarClient.Ado.BeginTranAsync(); + return dbContext; + } + + return (TDbContext)activeTransaction.GetDbContext(); + } } \ No newline at end of file diff --git a/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditLogInfoToAuditLogConverter.cs b/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditLogInfoToAuditLogConverter.cs index d1cf80e..d2b69f2 100644 --- a/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditLogInfoToAuditLogConverter.cs +++ b/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditLogInfoToAuditLogConverter.cs @@ -1,88 +1,89 @@ -using NPin.Framework.AuditLogging.Domain.Entities; -using Volo.Abp.AspNetCore.ExceptionHandling; -using Volo.Abp.Auditing; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Guids; -using Volo.Abp.Json; - -namespace NPin.Framework.AuditLogging.Domain; - -public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency -{ - protected IGuidGenerator GuidGenerator { get; } - protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; } - protected IJsonSerializer JsonSerializer { get; } - protected AbpExceptionHandlingOptions ExceptionHandlingOptions { get; } - - public AuditLogInfoToAuditLogConverter(IGuidGenerator guidGenerator, - IExceptionToErrorInfoConverter exceptionToErrorInfoConverter, IJsonSerializer jsonSerializer, - AbpExceptionHandlingOptions exceptionHandlingOptions) - { - GuidGenerator = guidGenerator; - ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter; - JsonSerializer = jsonSerializer; - ExceptionHandlingOptions = exceptionHandlingOptions; - } - - public virtual Task ConvertAsync(AuditLogInfo auditLogInfo) - { - var auditLogId = GuidGenerator.Create(); - - var extraProperties = new ExtraPropertyDictionary(); - foreach (var pair in auditLogInfo.ExtraProperties) - { - extraProperties.Add(pair.Key, pair.Value); - } - - var entityChanges = auditLogInfo.EntityChanges? - .Select(info => new EntityChangeEntity(GuidGenerator, auditLogId, info, auditLogInfo.TenantId)) - .ToList() ?? []; - var actions = auditLogInfo.Actions? - .Select(info => new AuditLogActionEntity(GuidGenerator.Create(), auditLogId, info, auditLogInfo.TenantId)) - .ToList() ?? []; - var remoteServiceErrorInfos = auditLogInfo.Exceptions? - .Select(ex => ExceptionToErrorInfoConverter.Convert(ex, options => - { - options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients; - options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients; - })) ?? []; - - var exceptions = remoteServiceErrorInfos.Any() - ? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true) - : null; - - var comments = auditLogInfo.Comments? - .JoinAsString(Environment.NewLine); - - var auditLog = new AuditLogAggregateRoot( - auditLogId, - auditLogInfo.ApplicationName, - auditLogInfo.UserId, - auditLogInfo.UserName, - auditLogInfo.TenantName, - auditLogInfo.ImpersonatorUserId, - auditLogInfo.ImpersonatorUserName, - auditLogInfo.ImpersonatorTenantId, - auditLogInfo.ImpersonatorTenantName, - auditLogInfo.ExecutionTime, - auditLogInfo.ExecutionDuration, - auditLogInfo.ClientIpAddress, - auditLogInfo.ClientName, - auditLogInfo.ClientId, - auditLogInfo.CorrelationId, - auditLogInfo.BrowserInfo, - auditLogInfo.HttpMethod, - auditLogInfo.Url, - exceptions, - comments, - auditLogInfo.HttpStatusCode, - auditLogInfo.TenantId, - entityChanges, - actions, - extraProperties - ); - - return Task.FromResult(auditLog); - } +using Microsoft.Extensions.Options; +using NPin.Framework.AuditLogging.Domain.Entities; +using Volo.Abp.AspNetCore.ExceptionHandling; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.Json; + +namespace NPin.Framework.AuditLogging.Domain; + +public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency +{ + protected IGuidGenerator GuidGenerator { get; } + protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; } + protected IJsonSerializer JsonSerializer { get; } + protected AbpExceptionHandlingOptions ExceptionHandlingOptions { get; } + + public AuditLogInfoToAuditLogConverter(IGuidGenerator guidGenerator, + IExceptionToErrorInfoConverter exceptionToErrorInfoConverter, IJsonSerializer jsonSerializer, + IOptions exceptionHandlingOptions) + { + GuidGenerator = guidGenerator; + ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter; + JsonSerializer = jsonSerializer; + ExceptionHandlingOptions = exceptionHandlingOptions.Value; + } + + public virtual Task ConvertAsync(AuditLogInfo auditLogInfo) + { + var auditLogId = GuidGenerator.Create(); + + var extraProperties = new ExtraPropertyDictionary(); + foreach (var pair in auditLogInfo.ExtraProperties) + { + extraProperties.Add(pair.Key, pair.Value); + } + + var entityChanges = auditLogInfo.EntityChanges? + .Select(info => new EntityChangeEntity(GuidGenerator, auditLogId, info, auditLogInfo.TenantId)) + .ToList() ?? []; + var actions = auditLogInfo.Actions? + .Select(info => new AuditLogActionEntity(GuidGenerator.Create(), auditLogId, info, auditLogInfo.TenantId)) + .ToList() ?? []; + var remoteServiceErrorInfos = auditLogInfo.Exceptions? + .Select(ex => ExceptionToErrorInfoConverter.Convert(ex, options => + { + options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients; + options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients; + })) ?? []; + + var exceptions = remoteServiceErrorInfos.Any() + ? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true) + : null; + + var comments = auditLogInfo.Comments? + .JoinAsString(Environment.NewLine); + + var auditLog = new AuditLogAggregateRoot( + auditLogId, + auditLogInfo.ApplicationName, + auditLogInfo.UserId, + auditLogInfo.UserName, + auditLogInfo.TenantName, + auditLogInfo.ImpersonatorUserId, + auditLogInfo.ImpersonatorUserName, + auditLogInfo.ImpersonatorTenantId, + auditLogInfo.ImpersonatorTenantName, + auditLogInfo.ExecutionTime, + auditLogInfo.ExecutionDuration, + auditLogInfo.ClientIpAddress, + auditLogInfo.ClientName, + auditLogInfo.ClientId, + auditLogInfo.CorrelationId, + auditLogInfo.BrowserInfo, + auditLogInfo.HttpMethod, + auditLogInfo.Url, + exceptions, + comments, + auditLogInfo.HttpStatusCode, + auditLogInfo.TenantId, + entityChanges, + actions, + extraProperties + ); + + return Task.FromResult(auditLog); + } } \ No newline at end of file diff --git a/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditingStore.cs b/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditingStore.cs index 68b0e50..ffccd91 100644 --- a/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditingStore.cs +++ b/module/audit-logging/NPin.Framework.AuditLogging.Domain/AuditingStore.cs @@ -1,60 +1,61 @@ -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using NPin.Framework.AuditLogging.Domain.Repositories; -using Volo.Abp.Auditing; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Uow; - -namespace NPin.Framework.AuditLogging.Domain; - -public class AuditingStore : IAuditingStore, ITransientDependency -{ - public ILogger Logger { get; set; } - protected IAuditLogRepository AuditLogRepository { get; } - protected IUnitOfWorkManager UnitOfWorkManager { get; } - protected AbpAuditingOptions Options { get; } - protected IAuditLogInfoToAuditLogConverter Converter { get; } - - public AuditingStore(ILogger logger, IAuditLogRepository auditLogRepository, - IUnitOfWorkManager unitOfWorkManager, AbpAuditingOptions options, IAuditLogInfoToAuditLogConverter converter) - { - Logger = logger; - AuditLogRepository = auditLogRepository; - UnitOfWorkManager = unitOfWorkManager; - Options = options; - Converter = converter; - } - - public virtual async Task SaveAsync(AuditLogInfo auditInfo) - { - if (!Options.HideErrors) - { - await SaveLogAsync(auditInfo); - return; - } - - try - { - await SaveLogAsync(auditInfo); - } - catch (Exception ex) - { - Logger.LogWarning($"无法保存审计日志: {Environment.NewLine}{auditInfo}"); - Logger.LogException(ex, LogLevel.Error); - } - } - - protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo) - { - var timeConverter = new IsoDateTimeConverter - { - DateTimeFormat = "yyyy-MM-dd HH:mm:ss" - }; - Logger.LogDebug($"NPin-请求日志:{JsonConvert.SerializeObject(auditInfo, Formatting.Indented, timeConverter)}"); - - using var uow = UnitOfWorkManager.Begin(true); - await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo)); - await uow.CompleteAsync(); - } +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using NPin.Framework.AuditLogging.Domain.Repositories; +using Volo.Abp.Auditing; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Uow; + +namespace NPin.Framework.AuditLogging.Domain; + +public class AuditingStore : IAuditingStore, ITransientDependency +{ + public ILogger Logger { get; set; } + protected IAuditLogRepository AuditLogRepository { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + protected AbpAuditingOptions Options { get; } + protected IAuditLogInfoToAuditLogConverter Converter { get; } + + public AuditingStore(ILogger logger, IAuditLogRepository auditLogRepository, + IUnitOfWorkManager unitOfWorkManager, IOptions options, IAuditLogInfoToAuditLogConverter converter) + { + Logger = logger; + AuditLogRepository = auditLogRepository; + UnitOfWorkManager = unitOfWorkManager; + Options = options.Value; + Converter = converter; + } + + public virtual async Task SaveAsync(AuditLogInfo auditInfo) + { + if (!Options.HideErrors) + { + await SaveLogAsync(auditInfo); + return; + } + + try + { + await SaveLogAsync(auditInfo); + } + catch (Exception ex) + { + Logger.LogWarning($"无法保存审计日志: {Environment.NewLine}{auditInfo}"); + Logger.LogException(ex, LogLevel.Error); + } + } + + protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo) + { + var timeConverter = new IsoDateTimeConverter + { + DateTimeFormat = "yyyy-MM-dd HH:mm:ss" + }; + Logger.LogDebug($"NPin-请求日志:{JsonConvert.SerializeObject(auditInfo, Formatting.Indented, timeConverter)}"); + + using var uow = UnitOfWorkManager.Begin(true); + await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo)); + await uow.CompleteAsync(); + } } \ No newline at end of file diff --git a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogActionEntity.cs b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogActionEntity.cs index 33e6d01..c3a33d8 100644 --- a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogActionEntity.cs +++ b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogActionEntity.cs @@ -1,51 +1,51 @@ -using NPin.Framework.AuditLogging.Domain.Shared.Consts; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; -using Volo.Abp.MultiTenancy; - -namespace NPin.Framework.AuditLogging.Domain.Entities; - -[DisableAuditing] -[SugarTable("NPinAuditLogAction", "审计日志操作表")] -[SugarIndex($"index_{nameof(AuditLogId)}", nameof(AuditLogId), OrderByType.Asc)] -[SugarIndex($"index_{nameof(TenantId)}_{nameof(ExecutionTime)}", nameof(TenantId), OrderByType.Asc, nameof(ServiceName), - OrderByType.Asc, nameof(MethodName), OrderByType.Asc, nameof(ExecutionTime), OrderByType.Asc)] -public class AuditLogActionEntity : Entity, IMultiTenant -{ - public virtual Guid? TenantId { get; protected set; } - - public virtual Guid AuditLogId { get; protected set; } - - public virtual string? ServiceName { get; protected set; } - - public virtual string? MethodName { get; protected set; } - - public virtual string? Parameters { get; protected set; } - - public virtual DateTime? ExecutionTime { get; protected set; } - - public virtual int? ExecutionDuration { get; protected set; } - - [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - public AuditLogActionEntity() - { - } - - public AuditLogActionEntity(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null) - { - Id = id; - TenantId = tenantId; - AuditLogId = auditLogId; - ExecutionTime = actionInfo.ExecutionTime; - ExecutionDuration = actionInfo.ExecutionDuration; - - ServiceName = actionInfo.ServiceName.TruncateFromBeginning(AuditLogActionConsts.MaxServiceNameLength); - MethodName = actionInfo.MethodName.TruncateFromBeginning(AuditLogActionConsts.MaxMethodNameLength); - Parameters = actionInfo.Parameters.Length > AuditLogActionConsts.MaxParametersLength - ? "" - : actionInfo.Parameters; - } +using NPin.Framework.AuditLogging.Domain.Shared.Consts; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace NPin.Framework.AuditLogging.Domain.Entities; + +[DisableAuditing] +[SugarTable("SysAuditLogAction", "审计日志操作表")] +[SugarIndex($"index_{nameof(AuditLogId)}", nameof(AuditLogId), OrderByType.Asc)] +[SugarIndex($"index_{nameof(TenantId)}_{nameof(ExecutionTime)}", nameof(TenantId), OrderByType.Asc, nameof(ServiceName), + OrderByType.Asc, nameof(MethodName), OrderByType.Asc, nameof(ExecutionTime), OrderByType.Asc)] +public class AuditLogActionEntity : Entity, IMultiTenant +{ + public virtual Guid? TenantId { get; protected set; } + + public virtual Guid AuditLogId { get; protected set; } + + public virtual string? ServiceName { get; protected set; } + + public virtual string? MethodName { get; protected set; } + + public virtual string? Parameters { get; protected set; } + + public virtual DateTime? ExecutionTime { get; protected set; } + + public virtual int? ExecutionDuration { get; protected set; } + + [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + public AuditLogActionEntity() + { + } + + public AuditLogActionEntity(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null) + { + Id = id; + TenantId = tenantId; + AuditLogId = auditLogId; + ExecutionTime = actionInfo.ExecutionTime; + ExecutionDuration = actionInfo.ExecutionDuration; + + ServiceName = actionInfo.ServiceName.TruncateFromBeginning(AuditLogActionConsts.MaxServiceNameLength); + MethodName = actionInfo.MethodName.TruncateFromBeginning(AuditLogActionConsts.MaxMethodNameLength); + Parameters = actionInfo.Parameters.Length > AuditLogActionConsts.MaxParametersLength + ? "" + : actionInfo.Parameters; + } } \ No newline at end of file diff --git a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogAggregateRoot.cs b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogAggregateRoot.cs index 2a9213c..50243f1 100644 --- a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogAggregateRoot.cs +++ b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/AuditLogAggregateRoot.cs @@ -1,111 +1,111 @@ -using NPin.Framework.AuditLogging.Domain.Shared.Consts; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Data; -using Volo.Abp.Domain.Entities; -using Volo.Abp.MultiTenancy; - -namespace NPin.Framework.AuditLogging.Domain.Entities; - -[DisableAuditing] -[SugarTable("NPinAuditLog", "审计日志")] -[SugarIndex($"index_{nameof(ExecutionTime)}", nameof(TenantId), OrderByType.Asc, nameof(ExecutionTime), - OrderByType.Asc)] -[SugarIndex($"index_{nameof(ExecutionTime)}_{nameof(UserId)}", nameof(TenantId), OrderByType.Asc, nameof(UserId), - OrderByType.Asc, nameof(ExecutionTime), OrderByType.Asc)] -public class AuditLogAggregateRoot : AggregateRoot, IMultiTenant -{ - [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - public virtual string? ApplicationName { get; set; } - - - public virtual Guid? UserId { get; protected set; } - - public virtual string? UserName { get; protected set; } - - public virtual string? TenantName { get; protected set; } - - public virtual Guid? ImpersonatorUserId { get; protected set; } - - public virtual string? ImpersonatorUserName { get; protected set; } - - public virtual Guid? ImpersonatorTenantId { get; protected set; } - - public virtual string? ImpersonatorTenantName { get; protected set; } - - public virtual DateTime? ExecutionTime { get; protected set; } - - public virtual int? ExecutionDuration { get; protected set; } - - public virtual string? ClientIpAddress { get; protected set; } - - public virtual string? ClientName { get; protected set; } - - public virtual string? ClientId { get; set; } - - public virtual string? CorrelationId { get; set; } - - public virtual string? BrowserInfo { get; protected set; } - - public virtual string? HttpMethod { get; protected set; } - - public virtual string? Url { get; protected set; } - - public virtual string? Exceptions { get; protected set; } - - public virtual string? Comments { get; protected set; } - - public virtual int? HttpStatusCode { get; set; } - - public virtual Guid? TenantId { get; protected set; } - - // 导航属性 - [Navigate(NavigateType.OneToMany, nameof(EntityChangeEntity.AuditLogId))] - public virtual List EntityChanges { get; protected set; } - - // 导航属性 - [Navigate(NavigateType.OneToMany, nameof(AuditLogActionEntity.AuditLogId))] - public virtual List Actions { get; protected set; } - - [SugarColumn(IsIgnore = true)] public override ExtraPropertyDictionary ExtraProperties { get; protected set; } - - public AuditLogAggregateRoot() - { - } - - public AuditLogAggregateRoot(Guid id, string? applicationName, Guid? userId, string? userName, string? tenantName, - Guid? impersonatorUserId, string? impersonatorUserName, Guid? impersonatorTenantId, - string? impersonatorTenantName, DateTime? executionTime, int? executionDuration, string? clientIpAddress, - string? clientName, string? clientId, string? correlationId, string? browserInfo, string? httpMethod, - string? url, string? exceptions, string? comments, int? httpStatusCode, Guid? tenantId, - List entityChanges, List actions, - ExtraPropertyDictionary extraProperties) : base(id) - { - ApplicationName = applicationName.Truncate(AuditLogConsts.MaxApplicationNameLength); - UserId = userId; - UserName = userName.Truncate(AuditLogConsts.MaxUserNameLength); - TenantName = tenantName.Truncate(AuditLogConsts.MaxTenantNameLength); - ImpersonatorUserId = impersonatorUserId; - ImpersonatorUserName = impersonatorUserName.Truncate(AuditLogConsts.MaxUserNameLength); - ImpersonatorTenantId = impersonatorTenantId; - ImpersonatorTenantName = impersonatorTenantName.Truncate(AuditLogConsts.MaxTenantNameLength); - ExecutionTime = executionTime; - ExecutionDuration = executionDuration; - ClientIpAddress = clientIpAddress.Truncate(AuditLogConsts.MaxClientIpAddressLength); - ClientName = clientName.Truncate(AuditLogConsts.MaxClientNameLength); - ClientId = clientId.Truncate(AuditLogConsts.MaxClientIdLength); - CorrelationId = correlationId.Truncate(AuditLogConsts.MaxCorrelationIdLength); - BrowserInfo = browserInfo.Truncate(AuditLogConsts.MaxBrowserInfoLength); - HttpMethod = httpMethod.Truncate(AuditLogConsts.MaxHttpMethodLength); - Url = url.Truncate(AuditLogConsts.MaxUrlLength); - Exceptions = exceptions; - Comments = comments.Truncate(AuditLogConsts.MaxCommentsLength); - HttpStatusCode = httpStatusCode; - TenantId = tenantId; - EntityChanges = entityChanges; - Actions = actions; - ExtraProperties = extraProperties; - } +using NPin.Framework.AuditLogging.Domain.Shared.Consts; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace NPin.Framework.AuditLogging.Domain.Entities; + +[DisableAuditing] +[SugarTable("SysAuditLog", "审计日志")] +[SugarIndex($"index_{nameof(ExecutionTime)}", nameof(TenantId), OrderByType.Asc, nameof(ExecutionTime), + OrderByType.Asc)] +[SugarIndex($"index_{nameof(ExecutionTime)}_{nameof(UserId)}", nameof(TenantId), OrderByType.Asc, nameof(UserId), + OrderByType.Asc, nameof(ExecutionTime), OrderByType.Asc)] +public class AuditLogAggregateRoot : AggregateRoot, IMultiTenant +{ + [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + public virtual string? ApplicationName { get; set; } + + + public virtual Guid? UserId { get; protected set; } + + public virtual string? UserName { get; protected set; } + + public virtual string? TenantName { get; protected set; } + + public virtual Guid? ImpersonatorUserId { get; protected set; } + + public virtual string? ImpersonatorUserName { get; protected set; } + + public virtual Guid? ImpersonatorTenantId { get; protected set; } + + public virtual string? ImpersonatorTenantName { get; protected set; } + + public virtual DateTime? ExecutionTime { get; protected set; } + + public virtual int? ExecutionDuration { get; protected set; } + + public virtual string? ClientIpAddress { get; protected set; } + + public virtual string? ClientName { get; protected set; } + + public virtual string? ClientId { get; set; } + + public virtual string? CorrelationId { get; set; } + + public virtual string? BrowserInfo { get; protected set; } + + public virtual string? HttpMethod { get; protected set; } + + public virtual string? Url { get; protected set; } + + public virtual string? Exceptions { get; protected set; } + + public virtual string? Comments { get; protected set; } + + public virtual int? HttpStatusCode { get; set; } + + public virtual Guid? TenantId { get; protected set; } + + // 导航属性 + [Navigate(NavigateType.OneToMany, nameof(EntityChangeEntity.AuditLogId))] + public virtual List EntityChanges { get; protected set; } + + // 导航属性 + [Navigate(NavigateType.OneToMany, nameof(AuditLogActionEntity.AuditLogId))] + public virtual List Actions { get; protected set; } + + [SugarColumn(IsIgnore = true)] public override ExtraPropertyDictionary ExtraProperties { get; protected set; } + + public AuditLogAggregateRoot() + { + } + + public AuditLogAggregateRoot(Guid id, string? applicationName, Guid? userId, string? userName, string? tenantName, + Guid? impersonatorUserId, string? impersonatorUserName, Guid? impersonatorTenantId, + string? impersonatorTenantName, DateTime? executionTime, int? executionDuration, string? clientIpAddress, + string? clientName, string? clientId, string? correlationId, string? browserInfo, string? httpMethod, + string? url, string? exceptions, string? comments, int? httpStatusCode, Guid? tenantId, + List entityChanges, List actions, + ExtraPropertyDictionary extraProperties) : base(id) + { + ApplicationName = applicationName.Truncate(AuditLogConsts.MaxApplicationNameLength); + UserId = userId; + UserName = userName.Truncate(AuditLogConsts.MaxUserNameLength); + TenantName = tenantName.Truncate(AuditLogConsts.MaxTenantNameLength); + ImpersonatorUserId = impersonatorUserId; + ImpersonatorUserName = impersonatorUserName.Truncate(AuditLogConsts.MaxUserNameLength); + ImpersonatorTenantId = impersonatorTenantId; + ImpersonatorTenantName = impersonatorTenantName.Truncate(AuditLogConsts.MaxTenantNameLength); + ExecutionTime = executionTime; + ExecutionDuration = executionDuration; + ClientIpAddress = clientIpAddress.Truncate(AuditLogConsts.MaxClientIpAddressLength); + ClientName = clientName.Truncate(AuditLogConsts.MaxClientNameLength); + ClientId = clientId.Truncate(AuditLogConsts.MaxClientIdLength); + CorrelationId = correlationId.Truncate(AuditLogConsts.MaxCorrelationIdLength); + BrowserInfo = browserInfo.Truncate(AuditLogConsts.MaxBrowserInfoLength); + HttpMethod = httpMethod.Truncate(AuditLogConsts.MaxHttpMethodLength); + Url = url.Truncate(AuditLogConsts.MaxUrlLength); + Exceptions = exceptions; + Comments = comments.Truncate(AuditLogConsts.MaxCommentsLength); + HttpStatusCode = httpStatusCode; + TenantId = tenantId; + EntityChanges = entityChanges; + Actions = actions; + ExtraProperties = extraProperties; + } } \ No newline at end of file diff --git a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityChangeEntity.cs b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityChangeEntity.cs index fadddb6..ba9f53d 100644 --- a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityChangeEntity.cs +++ b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityChangeEntity.cs @@ -1,63 +1,63 @@ -using NPin.Framework.AuditLogging.Domain.Shared.Consts; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Guids; -using Volo.Abp.MultiTenancy; - -namespace NPin.Framework.AuditLogging.Domain.Entities; - -[SugarTable("NPinEntityChange")] -[SugarIndex($"index_{nameof(AuditLogId)}", nameof(AuditLogId), OrderByType.Asc)] -[SugarIndex($"index_{nameof(TenantId)}_{nameof(EntityId)}", nameof(TenantId), OrderByType.Asc, - nameof(EntityTypeFullName), OrderByType.Asc, nameof(EntityId), OrderByType.Asc)] -public class EntityChangeEntity : Entity, IMultiTenant -{ - [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - public virtual Guid AuditLogId { get; protected set; } - - public virtual Guid? TenantId { get; protected set; } - - public virtual DateTime? ChangeTime { get; protected set; } - - public virtual EntityChangeType? ChangeType { get; protected set; } - - public virtual Guid? EntityTenantId { get; protected set; } - - public virtual string? EntityId { get; protected set; } - - public virtual string? EntityTypeFullName { get; protected set; } - - // 关联 - [Navigate(NavigateType.OneToMany, nameof(EntityPropertyChangeEntity.EntityChangeId))] - public virtual List PropertyChanges { get; protected set; } - - public EntityChangeEntity() - { - } - - public EntityChangeEntity( - IGuidGenerator guidGenerator, - Guid auditLogId, - EntityChangeInfo entityChangeInfo, - Guid? tenantId = null) - { - Id = guidGenerator.Create(); - AuditLogId = auditLogId; - TenantId = tenantId; - ChangeTime = entityChangeInfo.ChangeTime; - ChangeType = entityChangeInfo.ChangeType; - EntityTenantId = entityChangeInfo.EntityTenantId; - EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityTypeFullNameLength); - EntityTypeFullName = - entityChangeInfo.EntityTypeFullName.TruncateFromBeginning(EntityChangeConsts.MaxEntityTypeFullNameLength); - - PropertyChanges = entityChangeInfo - .PropertyChanges? - .Select(p => new EntityPropertyChangeEntity(guidGenerator, Id, p, tenantId)) - .ToList() - ?? new List(); - } +using NPin.Framework.AuditLogging.Domain.Shared.Consts; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace NPin.Framework.AuditLogging.Domain.Entities; + +[SugarTable("SysEntityChange")] +[SugarIndex($"index_{nameof(AuditLogId)}", nameof(AuditLogId), OrderByType.Asc)] +[SugarIndex($"index_{nameof(TenantId)}_{nameof(EntityId)}", nameof(TenantId), OrderByType.Asc, + nameof(EntityTypeFullName), OrderByType.Asc, nameof(EntityId), OrderByType.Asc)] +public class EntityChangeEntity : Entity, IMultiTenant +{ + [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + public virtual Guid AuditLogId { get; protected set; } + + public virtual Guid? TenantId { get; protected set; } + + public virtual DateTime? ChangeTime { get; protected set; } + + public virtual EntityChangeType? ChangeType { get; protected set; } + + public virtual Guid? EntityTenantId { get; protected set; } + + public virtual string? EntityId { get; protected set; } + + public virtual string? EntityTypeFullName { get; protected set; } + + // 关联 + [Navigate(NavigateType.OneToMany, nameof(EntityPropertyChangeEntity.EntityChangeId))] + public virtual List PropertyChanges { get; protected set; } + + public EntityChangeEntity() + { + } + + public EntityChangeEntity( + IGuidGenerator guidGenerator, + Guid auditLogId, + EntityChangeInfo entityChangeInfo, + Guid? tenantId = null) + { + Id = guidGenerator.Create(); + AuditLogId = auditLogId; + TenantId = tenantId; + ChangeTime = entityChangeInfo.ChangeTime; + ChangeType = entityChangeInfo.ChangeType; + EntityTenantId = entityChangeInfo.EntityTenantId; + EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityTypeFullNameLength); + EntityTypeFullName = + entityChangeInfo.EntityTypeFullName.TruncateFromBeginning(EntityChangeConsts.MaxEntityTypeFullNameLength); + + PropertyChanges = entityChangeInfo + .PropertyChanges? + .Select(p => new EntityPropertyChangeEntity(guidGenerator, Id, p, tenantId)) + .ToList() + ?? new List(); + } } \ No newline at end of file diff --git a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityPropertyChangeEntity.cs b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityPropertyChangeEntity.cs index ab2057a..d02a9e6 100644 --- a/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityPropertyChangeEntity.cs +++ b/module/audit-logging/NPin.Framework.AuditLogging.Domain/Entities/EntityPropertyChangeEntity.cs @@ -1,50 +1,50 @@ -using NPin.Framework.AuditLogging.Domain.Shared.Consts; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Guids; -using Volo.Abp.MultiTenancy; - -namespace NPin.Framework.AuditLogging.Domain.Entities; - -[SugarTable("NPinEntityPropertyChange")] -[SugarIndex($"index_{nameof(EntityChangeId)}", nameof(EntityChangeId), OrderByType.Asc)] -public class EntityPropertyChangeEntity : Entity, IMultiTenant -{ - [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - public virtual Guid? TenantId { get; protected set; } - public virtual Guid? EntityChangeId { get; protected set; } - - public virtual string? NewValue { get; protected set; } - - public virtual string? OriginalValue { get; protected set; } - - public virtual string? PropertyName { get; protected set; } - - public virtual string? PropertyTypeFullName { get; protected set; } - - public EntityPropertyChangeEntity() - { - } - - - public EntityPropertyChangeEntity( - IGuidGenerator guidGenerator, - Guid entityChangeId, - EntityPropertyChangeInfo entityChangeInfo, - Guid? tenantId = null) - { - Id = guidGenerator.Create(); - TenantId = tenantId; - EntityChangeId = entityChangeId; - NewValue = entityChangeInfo.NewValue.Truncate(EntityPropertyChangeConsts.MaxNewValueLength); - OriginalValue = entityChangeInfo.OriginalValue.Truncate(EntityPropertyChangeConsts.MaxOriginalValueLength); - PropertyName = - entityChangeInfo.PropertyName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyNameLength); - PropertyTypeFullName = - entityChangeInfo.PropertyTypeFullName.TruncateFromBeginning(EntityPropertyChangeConsts - .MaxPropertyTypeFullNameLength); - } +using NPin.Framework.AuditLogging.Domain.Shared.Consts; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace NPin.Framework.AuditLogging.Domain.Entities; + +[SugarTable("SysEntityPropertyChange")] +[SugarIndex($"index_{nameof(EntityChangeId)}", nameof(EntityChangeId), OrderByType.Asc)] +public class EntityPropertyChangeEntity : Entity, IMultiTenant +{ + [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + public virtual Guid? TenantId { get; protected set; } + public virtual Guid? EntityChangeId { get; protected set; } + + public virtual string? NewValue { get; protected set; } + + public virtual string? OriginalValue { get; protected set; } + + public virtual string? PropertyName { get; protected set; } + + public virtual string? PropertyTypeFullName { get; protected set; } + + public EntityPropertyChangeEntity() + { + } + + + public EntityPropertyChangeEntity( + IGuidGenerator guidGenerator, + Guid entityChangeId, + EntityPropertyChangeInfo entityChangeInfo, + Guid? tenantId = null) + { + Id = guidGenerator.Create(); + TenantId = tenantId; + EntityChangeId = entityChangeId; + NewValue = entityChangeInfo.NewValue.Truncate(EntityPropertyChangeConsts.MaxNewValueLength); + OriginalValue = entityChangeInfo.OriginalValue.Truncate(EntityPropertyChangeConsts.MaxOriginalValueLength); + PropertyName = + entityChangeInfo.PropertyName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyNameLength); + PropertyTypeFullName = + entityChangeInfo.PropertyTypeFullName.TruncateFromBeginning(EntityPropertyChangeConsts + .MaxPropertyTypeFullNameLength); + } } \ No newline at end of file diff --git a/module/setting-management/NPin.Framework.SettingManagement.Domain/Entities/SettingEntity.cs b/module/setting-management/NPin.Framework.SettingManagement.Domain/Entities/SettingEntity.cs index 4fffffb..69ec9a4 100644 --- a/module/setting-management/NPin.Framework.SettingManagement.Domain/Entities/SettingEntity.cs +++ b/module/setting-management/NPin.Framework.SettingManagement.Domain/Entities/SettingEntity.cs @@ -1,38 +1,40 @@ using JetBrains.Annotations; +using SqlSugar; using Volo.Abp.Domain.Entities; +using Check = Volo.Abp.Check; namespace NPin.Framework.SettingManagement.Domain.Entities; -public class SettingEntity: Entity, IAggregateRoot +[SugarTable("SysSetting", "系统配置表")] +public class SettingEntity : Entity, IAggregateRoot { - [NotNull] - public virtual string Name { get; protected set; } + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - [NotNull] - public virtual string Value { get; internal set; } + [SugarColumn(ColumnDescription = "配置名称")] + public string Name { get; protected set; } - [CanBeNull] - public virtual string ProviderName { get; protected set; } + [SugarColumn(ColumnDescription = "配置值", ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string Value { get; internal set; } - [CanBeNull] - public virtual string ProviderKey { get; protected set; } + [SugarColumn(ColumnDescription = "配置提供者")] + public string? ProviderName { get; protected set; } + + [SugarColumn(ColumnDescription = "配置提供者Key")] + public string? ProviderKey { get; protected set; } public SettingEntity() { - } - + public SettingEntity( - Guid id, - [NotNull] string name, - [NotNull] string value, - [CanBeNull] string providerName = null, - [CanBeNull] string providerKey = null) + string name, + string value, + string? providerName = null, + string? providerKey = null) { Check.NotNull(name, nameof(name)); Check.NotNull(value, nameof(value)); - Id = id; Name = name; Value = value; ProviderName = providerName; @@ -41,6 +43,7 @@ public class SettingEntity: Entity, IAggregateRoot public override string ToString() { - return $"{base.ToString()}, Name = {Name}, Value = {Value}, ProviderName = {ProviderName}, ProviderKey = {ProviderKey}"; + return + $"{base.ToString()}, Name = {Name}, Value = {Value}, ProviderName = {ProviderName}, ProviderKey = {ProviderKey}"; } } \ No newline at end of file diff --git a/module/setting-management/NPin.Framework.SettingManagement.Domain/NPin.Framework.SettingManagement.Domain.csproj b/module/setting-management/NPin.Framework.SettingManagement.Domain/NPin.Framework.SettingManagement.Domain.csproj index 1aaa0fc..49ed1b8 100644 --- a/module/setting-management/NPin.Framework.SettingManagement.Domain/NPin.Framework.SettingManagement.Domain.csproj +++ b/module/setting-management/NPin.Framework.SettingManagement.Domain/NPin.Framework.SettingManagement.Domain.csproj @@ -10,5 +10,9 @@ + + + + diff --git a/module/setting-management/NPin.Framework.SettingManagement.Domain/SettingManager.cs b/module/setting-management/NPin.Framework.SettingManagement.Domain/SettingManager.cs index df1615b..9d067c0 100644 --- a/module/setting-management/NPin.Framework.SettingManagement.Domain/SettingManager.cs +++ b/module/setting-management/NPin.Framework.SettingManagement.Domain/SettingManager.cs @@ -10,6 +10,8 @@ namespace NPin.Framework.SettingManagement.Domain; public class SettingManager : ISettingManager, ISingletonDependency { private readonly Lazy> _lazyProviders; + + protected readonly IServiceProvider ServiceProvider; protected ISettingDefinitionManager SettingDefinitionManager { get; } protected ISettingEncryptionService SettingEncryptionService { get; } protected List Providers => _lazyProviders.Value; @@ -21,18 +23,21 @@ public class SettingManager : ISettingManager, ISingletonDependency ISettingEncryptionService settingEncryptionService, IOptions options) { + ServiceProvider = serviceProvider; SettingDefinitionManager = settingDefinitionManager; SettingEncryptionService = settingEncryptionService; Options = options.Value; - // TODO use IServiceScopeFactory and create a scope ? - _lazyProviders = new Lazy>( - () => Options - .Providers - .Select(c => serviceProvider.GetRequiredService(c) as ISettingManagementProvider) - .ToList(), - true - ); + _lazyProviders = new Lazy>(CreateSettingManagementProviders, true); + } + + protected virtual List CreateSettingManagementProviders() + { + using var scope = ServiceProvider.CreateScope(); + + return Options.Providers + .Select(p => (scope.ServiceProvider.GetRequiredService(p) as ISettingManagementProvider)!) + .ToList(); } public virtual Task GetOrNullAsync(string name, string providerName, string? providerKey, diff --git a/module/setting-management/NPin.Framework.SettingManagement.Domain/Store/SettingManagementStore.cs b/module/setting-management/NPin.Framework.SettingManagement.Domain/Store/SettingManagementStore.cs index 5c3c19f..d926276 100644 --- a/module/setting-management/NPin.Framework.SettingManagement.Domain/Store/SettingManagementStore.cs +++ b/module/setting-management/NPin.Framework.SettingManagement.Domain/Store/SettingManagementStore.cs @@ -13,16 +13,13 @@ public class SettingManagementStore : ISettingManagementStore, ITransientDepende protected IDistributedCache Cache { get; } protected ISettingDefinitionManager SettingDefinitionManager { get; } protected ISettingRepository SettingRepository { get; } - protected IGuidGenerator GuidGenerator { get; } public SettingManagementStore(IDistributedCache cache, - ISettingDefinitionManager settingDefinitionManager, ISettingRepository settingRepository, - IGuidGenerator guidGenerator) + ISettingDefinitionManager settingDefinitionManager, ISettingRepository settingRepository) { Cache = cache; SettingDefinitionManager = settingDefinitionManager; SettingRepository = settingRepository; - GuidGenerator = guidGenerator; } [UnitOfWork] @@ -65,7 +62,7 @@ public class SettingManagementStore : ISettingManagementStore, ITransientDepende var setting = await SettingRepository.FindAsync(name, providerName, providerKey); if (setting == null) { - setting = new SettingEntity(GuidGenerator.Create(), name, value, providerName, providerKey); + setting = new SettingEntity(name, value, providerName, providerKey); await SettingRepository.InsertAsync(setting); } else diff --git a/module/tenant-management/NPin.Framework.TenantManagement.Application/TenantService.cs b/module/tenant-management/NPin.Framework.TenantManagement.Application/TenantService.cs index 013263e..946b3a4 100644 --- a/module/tenant-management/NPin.Framework.TenantManagement.Application/TenantService.cs +++ b/module/tenant-management/NPin.Framework.TenantManagement.Application/TenantService.cs @@ -1,143 +1,152 @@ -using System.Reflection; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using NPin.Framework.Ddd.Application; -using NPin.Framework.SqlSugarCore.Abstractions; -using NPin.Framework.TenantManagement.Application.Contracts; -using NPin.Framework.TenantManagement.Application.Contracts.Dtos; -using NPin.Framework.TenantManagement.Domain; -using SqlSugar; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Data; -using Volo.Abp.Domain.Repositories; -using Volo.Abp.Modularity; - -namespace NPin.Framework.TenantManagement.Application; - -public class TenantService : NPinCrudAppService, ITenantService -{ - private ISqlSugarRepository _repository; - private IDataSeeder _dataSeeder; - - public TenantService(IRepository repository, - ISqlSugarRepository sqlSugarRepository, IDataSeeder dataSeeder) : base(repository) - { - _repository = sqlSugarRepository; - _dataSeeder = dataSeeder; - } - - /// - /// 多查 - /// - /// - /// - public override async Task> GetListAsync(TenantGetListInput input) - { - RefAsync total = 0; - var entities = await _repository.DbQueryable - .WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!)) - .WhereIF(input.StartTime is not null && input.EndTime is not null, - x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) - .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); - return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); - } - - /// - /// 租户选项列表(显示名称) - /// - /// - public async Task> GetSelectAsync() - { - var entities = await _repository.DbQueryable.ToListAsync(); - return entities.Select(x => new TenantSelectOutputDto { Id = x.Id, Name = x.Name }) - .ToList(); - } - - /// - /// 创建租户 - /// - /// - /// - public override async Task CreateAsync(TenantCreateInput input) - { - // 检查是否存在 - if (await _repository.IsAnyAsync(x => x.Name == input.Name)) - { - throw new UserFriendlyException("创建失败,当前租户已存在"); - } - - return await base.CreateAsync(input); - } - - /// - /// 更新租户信息 - /// - /// - /// - /// - public override async Task UpdateAsync(Guid id, TenantUpdateInput input) - { - if (await _repository.IsAnyAsync(x => x.Name == input.Name && x.Id != id)) - { - throw new UserFriendlyException("更新失败,更新后租户已存在"); - } - - return await base.UpdateAsync(id, input); - } - - // 只是为了可以在swagger上展示? - /// - /// 租户删除 - /// - /// - /// - public override Task DeleteAsync(IEnumerable ids) - { - return base.DeleteAsync(ids); - } - - /// - /// 初始化租户 - /// - /// - [HttpPost("tenant/init/{id}")] - public async Task InitAsync([FromRoute] Guid id) - { - using (CurrentTenant.Change(id)) - { - // 初始化 租户数据库/表 结构 - await CodeFirst(LazyServiceProvider); - // 插入 种子数据 - await _dataSeeder.SeedAsync(id); - } - } - - /// - /// 数据库 / 表 初始化 - /// - /// - private async Task CodeFirst(IServiceProvider service) - { - var moduleContainer = service.GetRequiredService(); - var db = await _repository.GetDbContextAsync(); - - // 尝试创建数据库 - db.DbMaintenance.CreateDatabase(); - - List types = new List(); - foreach (var module in moduleContainer.Modules) - { - types.AddRange(module.Assembly.GetTypes() - .Where(x => x.GetCustomAttribute() == null) - .Where(x => x.GetCustomAttribute() != null) - .Where(x => x.GetCustomAttribute() is null)); - } - - if (types.Count > 0) - { - db.CopyNew().CodeFirst.InitTables(types.ToArray()); - } - } +using System.Reflection; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using NPin.Framework.Ddd.Application; +using NPin.Framework.SqlSugarCore.Abstractions; +using NPin.Framework.TenantManagement.Application.Contracts; +using NPin.Framework.TenantManagement.Application.Contracts.Dtos; +using NPin.Framework.TenantManagement.Domain; +using SqlSugar; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Data; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Modularity; + +namespace NPin.Framework.TenantManagement.Application; + +public class TenantService : NPinCrudAppService, ITenantService +{ + private ISqlSugarRepository _repository; + private IDataSeeder _dataSeeder; + + public TenantService(IRepository repository, + ISqlSugarRepository sqlSugarRepository, IDataSeeder dataSeeder) : base(repository) + { + _repository = sqlSugarRepository; + _dataSeeder = dataSeeder; + } + + /// + /// 租户单查 + /// + /// 唯一ID + /// + public override Task GetAsync(Guid id) + { + return base.GetAsync(id); + } + + /// + /// 租户多查 + /// + /// + /// + public override async Task> GetListAsync(TenantGetListInput input) + { + RefAsync total = 0; + var entities = await _repository.DbQueryable + .WhereIF(!string.IsNullOrEmpty(input.Name), x => x.Name.Contains(input.Name!)) + .WhereIF(input.StartTime is not null && input.EndTime is not null, + x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) + .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); + return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); + } + + /// + /// 租户选项列表(显示名称) + /// + /// + public async Task> GetSelectAsync() + { + var entities = await _repository.DbQueryable.ToListAsync(); + return entities.Select(x => new TenantSelectOutputDto { Id = x.Id, Name = x.Name }) + .ToList(); + } + + /// + /// 创建租户 + /// + /// + /// + public override async Task CreateAsync(TenantCreateInput input) + { + // 检查是否存在 + if (await _repository.IsAnyAsync(x => x.Name == input.Name)) + { + throw new UserFriendlyException("创建失败,当前租户已存在"); + } + + return await base.CreateAsync(input); + } + + /// + /// 更新租户信息 + /// + /// + /// + /// + public override async Task UpdateAsync(Guid id, TenantUpdateInput input) + { + if (await _repository.IsAnyAsync(x => x.Name == input.Name && x.Id != id)) + { + throw new UserFriendlyException("更新失败,更新后租户已存在"); + } + + return await base.UpdateAsync(id, input); + } + + /// + /// 租户删除 + /// + /// + /// + public override Task DeleteAsync(IEnumerable ids) + { + return base.DeleteAsync(ids); + } + + /// + /// 初始化租户 + /// + /// + [HttpPost("tenant/init/{id}")] + public async Task InitAsync([FromRoute] Guid id) + { + using (CurrentTenant.Change(id)) + { + // 初始化 租户数据库/表 结构 + await CodeFirst(LazyServiceProvider); + // 插入 种子数据 + await _dataSeeder.SeedAsync(id); + } + } + + /// + /// 数据库 / 表 初始化 + /// + /// + private async Task CodeFirst(IServiceProvider service) + { + var moduleContainer = service.GetRequiredService(); + var db = await _repository.GetDbContextAsync(); + + // 尝试创建数据库 + db.DbMaintenance.CreateDatabase(); + + List types = new List(); + foreach (var module in moduleContainer.Modules) + { + types.AddRange(module.Assembly.GetTypes() + .Where(x => x.GetCustomAttribute() == null) + .Where(x => x.GetCustomAttribute() != null) + .Where(x => x.GetCustomAttribute() is null)); + } + + if (types.Count > 0) + { + db.CopyNew().CodeFirst.InitTables(types.ToArray()); + } + } } \ No newline at end of file diff --git a/module/tenant-management/NPin.Framework.TenantManagement.Domain/TenantAggregateRoot.cs b/module/tenant-management/NPin.Framework.TenantManagement.Domain/TenantAggregateRoot.cs index c975592..9a92cef 100644 --- a/module/tenant-management/NPin.Framework.TenantManagement.Domain/TenantAggregateRoot.cs +++ b/module/tenant-management/NPin.Framework.TenantManagement.Domain/TenantAggregateRoot.cs @@ -1,50 +1,50 @@ -using JetBrains.Annotations; -using NPin.Framework.SqlSugarCore.Abstractions; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Data; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.TenantManagement; -using Check = Volo.Abp.Check; - -namespace NPin.Framework.TenantManagement.Domain; - -[SugarTable("NPinTenant")] -[MasterTenant] -public class TenantAggregateRoot : FullAuditedAggregateRoot, IHasEntityVersion -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - public virtual string Name { get; protected set; } - public int EntityVersion { get; protected set; } - - public string TenantConnectionString { get; protected set; } - - public DbType DbType { get; protected set; } - - [SugarColumn(IsIgnore = true)] - public override ExtraPropertyDictionary ExtraProperties - { - get => base.ExtraProperties; - protected set => base.ExtraProperties = value; - } - - public virtual void SetConnectionString(DbType dbType, string connectionString) - { - DbType = dbType; - TenantConnectionString = connectionString; - } - - protected internal virtual void SetName([NotNull] string name) - { - Name = Check.NotNullOrWhiteSpace(name, nameof(name), TenantConsts.MaxNameLength); - } - - public TenantAggregateRoot() - { - } - - protected internal TenantAggregateRoot(Guid id, [NotNull] string name) : base(id) - { - SetName(name); - } +using JetBrains.Annotations; +using NPin.Framework.SqlSugarCore.Abstractions; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.TenantManagement; +using Check = Volo.Abp.Check; + +namespace NPin.Framework.TenantManagement.Domain; + +[SugarTable("SysTenant", "租户表")] +[MasterTenant] +public class TenantAggregateRoot : FullAuditedAggregateRoot, IHasEntityVersion +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + public virtual string Name { get; protected set; } + public int EntityVersion { get; protected set; } + + public string TenantConnectionString { get; protected set; } + + public DbType DbType { get; protected set; } + + [SugarColumn(IsIgnore = true)] + public override ExtraPropertyDictionary ExtraProperties + { + get => base.ExtraProperties; + protected set => base.ExtraProperties = value; + } + + public virtual void SetConnectionString(DbType dbType, string connectionString) + { + DbType = dbType; + TenantConnectionString = connectionString; + } + + protected internal virtual void SetName([NotNull] string name) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name), TenantConsts.MaxNameLength); + } + + public TenantAggregateRoot() + { + } + + protected internal TenantAggregateRoot(Guid id, [NotNull] string name) : base(id) + { + SetName(name); + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain.Shared/Consts/ConfigConst.cs b/module/upms/NPin.Framework.Upms.Domain.Shared/Consts/ConfigConst.cs index 9fcbd61..7c5e731 100644 --- a/module/upms/NPin.Framework.Upms.Domain.Shared/Consts/ConfigConst.cs +++ b/module/upms/NPin.Framework.Upms.Domain.Shared/Consts/ConfigConst.cs @@ -1,13 +1,18 @@ -namespace NPin.Framework.Upms.Domain.Shared.Consts; - -public class ConfigConst -{ - /// - /// 系统配置前缀 - /// - public const string SysConfigPrefix = "Sys"; - - public const string AliyunConfigKey = "Aliyun"; - public const string TencentConfigKey = "Tencent"; - public const string SmsConfigKey = "Sms"; +namespace NPin.Framework.Upms.Domain.Shared.Consts; + +public class ConfigConst +{ + /// + /// 系统配置前缀 + /// + public const string SysConfigPrefix = "sys"; + + /// + /// 短信配置相关 + /// + public const string SmsConfigKey = "sms"; + public const string SmsProvidersKey = $"{SysConfigPrefix}.{SmsConfigKey}.providers"; + public const string SmsTemplatesKey = $"{SysConfigPrefix}.{SmsConfigKey}.templates"; + public const string SmsSettingsKey = $"{SysConfigPrefix}.{SmsConfigKey}.settings"; + public const string SmsConfigModelKey = $"{SysConfigPrefix}.{SmsConfigKey}.config"; } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain.Shared/Enums/SmsEnum.cs b/module/upms/NPin.Framework.Upms.Domain.Shared/Enums/SmsEnum.cs index 2ef8710..6a68561 100644 --- a/module/upms/NPin.Framework.Upms.Domain.Shared/Enums/SmsEnum.cs +++ b/module/upms/NPin.Framework.Upms.Domain.Shared/Enums/SmsEnum.cs @@ -1,22 +1,22 @@ -using System.ComponentModel; - -namespace NPin.Framework.Upms.Domain.Shared.Enums; - -/// -/// 短信提供商枚举 -/// -public enum SmsProviderEnum -{ - Aliyun, - Tencent -} - -/// -/// 短信类型枚举 -/// -public enum SmsTypeEnum -{ - [Description("登录")] Login, - [Description("注册")] Register, - [Description("找回密码(重置密码)")] ResetPassword, +using System.ComponentModel; + +namespace NPin.Framework.Upms.Domain.Shared.Enums; + +/// +/// 短信提供商枚举 +/// +public enum SmsProviderTypeEnum +{ + Aliyun, + Tencent +} + +/// +/// 短信类型枚举 +/// +public enum SmsTypeEnum +{ + [Description("登录")] Login, + [Description("注册")] Register, + [Description("找回密码(重置密码)")] ResetPassword, } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain.Shared/Model/AliyunConfigModel.cs b/module/upms/NPin.Framework.Upms.Domain.Shared/Model/AliyunConfigModel.cs deleted file mode 100644 index 0bfa438..0000000 --- a/module/upms/NPin.Framework.Upms.Domain.Shared/Model/AliyunConfigModel.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace NPin.Framework.Upms.Domain.Shared.Model; - -public class AliyunConfigModel -{ - /// - /// 访问密钥Key - /// - public string AccessKeyId { get; set; } - - /// - /// 访问密钥 - /// - public string AccessKeySecret { get; set; } - - /// - /// 默认 区域ID - /// - public string RegionId { get; set; } - - /// - /// 默认 短信访问 端点 - /// - public string SmsEndpoint { get; set; } = "dysmsapi.aliyuncs.com"; -} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain.Shared/Model/SmsConfigModel.cs b/module/upms/NPin.Framework.Upms.Domain.Shared/Model/SmsConfigModel.cs index 34019fe..c3badc6 100644 --- a/module/upms/NPin.Framework.Upms.Domain.Shared/Model/SmsConfigModel.cs +++ b/module/upms/NPin.Framework.Upms.Domain.Shared/Model/SmsConfigModel.cs @@ -1,54 +1,128 @@ -using NPin.Framework.Upms.Domain.Shared.Enums; - -namespace NPin.Framework.Upms.Domain.Shared.Model; - -public class SmsConfigModel -{ - /// - /// 是否启用(总控) - /// - public bool Enabled { get; set; } = false; - - /// - /// 设定集 - /// - public Dictionary Settings { get; set; } -} - -public class SmsSettings -{ - /// - /// 是否启用 - /// - public bool Enabled { get; set; } = false; - - /// - /// 服务提供商 - /// - public SmsProviderEnum Provider { get; set; } - - /// - /// 区域 - /// - public string Region { get; set; } - - /// - /// 短信访问 端点 - /// - public string Endpoint { get; set; } - - /// - /// 短信签名名称 - /// - public string SignName { get; set; } - - /// - /// 短信模板Code - /// - public string TemplateCode { get; set; } - - /// - /// 过期时间,单位:秒 - /// - public int Expires { get; set; } +using Newtonsoft.Json; +using NPin.Framework.Upms.Domain.Shared.Enums; + +namespace NPin.Framework.Upms.Domain.Shared.Model; + +public class SmsConfigModel +{ + /// + /// 是否启用(总控) + /// + public bool Enabled { get; set; } = false; + + /// + /// 提供商列表 + /// + [JsonIgnore] + public List Providers { get; set; } = []; + + /// + /// 短信模板列表 + /// + [JsonIgnore] + public List Templates { get; set; } = []; + + /// + /// 系统短信设定集 + /// 类型:设定 + /// + [JsonIgnore] + public Dictionary Settings { get; set; } = new(); + + public SmsProvider GetProvider(SmsSettings settings) + { + return Providers.First(it => it.Id == settings.ProviderId); + } + + public SmsTemplate GetTemplate(SmsSettings settings) + { + return Templates.First(it => it.Id == settings.TemplateId); + } + + public SmsSettings? GetSetting(SmsTypeEnum typeEnum) + { + return Settings.GetValueOrDefault(typeEnum, null); + } +} + +/// +/// 短信提供商配置 +/// +public class SmsProvider +{ + /// + /// ID + /// + public Guid Id { get; set; } + + /// + /// 服务提供商 + /// + public SmsProviderTypeEnum ProviderType { get; set; } + + /// + /// 访问密钥Key + /// + public string AccessKeyId { get; set; } + + /// + /// 访问密钥 + /// + public string AccessKeySecret { get; set; } + + /// + /// 区域 + /// + public string Region { get; set; } + + /// + /// 短信访问 端点 + /// + public string Endpoint { get; set; } + + /// + /// 短信SdkAppId + /// + public string SmsSdkAppId { get; set; } +} + +public class SmsTemplate +{ + /// + /// ID + /// + public Guid Id { get; set; } + + /// + /// 短信签名名称 + /// + public string SignName { get; set; } + + /// + /// 短信模板Code + /// + public string TemplateCode { get; set; } +} + +public class SmsSettings +{ + /// + /// 短信类型 + /// + public SmsTypeEnum SmsType { get; set; } + + /// + /// 提供商ID + /// + public Guid ProviderId { get; set; } + + /// + /// 模板ID + /// + public Guid TemplateId { get; set; } + + /// + /// 过期时间,单位:秒 + /// + public int Expires { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain.Shared/Model/TencentConfigModel.cs b/module/upms/NPin.Framework.Upms.Domain.Shared/Model/TencentConfigModel.cs deleted file mode 100644 index 6bc6739..0000000 --- a/module/upms/NPin.Framework.Upms.Domain.Shared/Model/TencentConfigModel.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Newtonsoft.Json; - -namespace NPin.Framework.Upms.Domain.Shared.Model; - -public class TencentConfigModel -{ - /// - /// 访问密钥Key - /// - public string SecretId { get; set; } - - /// - /// 访问密钥 - /// - public string SecretKey { get; set; } - - /// - /// 默认区域 - /// - public string Region { get; set; } - - /// - /// 默认短信访问 端点 - /// - public string SmsEndpoint { get; set; } = "sms.tencentcloudapi.com"; - - /// - /// 短信SdkAppId - /// - public string SmsSdkAppId { get; set; } -} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Authorization/SocialAggregateRoot.cs b/module/upms/NPin.Framework.Upms.Domain/Authorization/SocialAggregateRoot.cs index 11e3d14..ad1130b 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Authorization/SocialAggregateRoot.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Authorization/SocialAggregateRoot.cs @@ -1,46 +1,46 @@ -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Data; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Authorization; - -[SugarTable("Social", "第三方授权表")] -public class SocialAggregateRoot: AggregateRoot, ISoftDelete, IHasCreationTime -{ - [SugarColumn(IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - public Guid UserId { get; set; } - - public string OpenId { get; set; } - - public string? UnionId { get; set; } - - public string Name { get; set; } - - public string Type { get; set; } - - public bool IsDeleted { get; } - public DateTime CreationTime { get; } - - [SugarColumn(IsIgnore = true)] - public override ExtraPropertyDictionary ExtraProperties { get; protected set; } - - public SocialAggregateRoot() - { - } - - public SocialAggregateRoot(string type, Guid userId, string openId, string? unionId) - { - UserId = userId; - OpenId = openId; - UnionId = unionId; - Type = type; - } - - public SocialAggregateRoot(string type, Guid userId, string openId, string? unionId, string name): this(type, userId, openId, unionId) - { - Name = name; - } +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Authorization; + +[SugarTable("SysSocial", "第三方授权表")] +public class SocialAggregateRoot: AggregateRoot, ISoftDelete, IHasCreationTime +{ + [SugarColumn(IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + public Guid UserId { get; set; } + + public string OpenId { get; set; } + + public string? UnionId { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } + + [SugarColumn(IsIgnore = true)] + public override ExtraPropertyDictionary ExtraProperties { get; protected set; } + + public SocialAggregateRoot() + { + } + + public SocialAggregateRoot(string type, Guid userId, string openId, string? unionId) + { + UserId = userId; + OpenId = openId; + UnionId = unionId; + Type = type; + } + + public SocialAggregateRoot(string type, Guid userId, string openId, string? unionId, string name): this(type, userId, openId, unionId) + { + Name = name; + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/AnnouncementEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/AnnouncementEntity.cs index 8d55e4b..69c05f4 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/AnnouncementEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/AnnouncementEntity.cs @@ -1,32 +1,32 @@ -using NPin.Framework.SqlSugarCore.Abstractions.Data; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("announcement", "系统公告表")] -public class AnnouncementEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "公告标题")] - public string Title { get; set; } - - [SugarColumn(ColumnDescription = "公告分类")] - public string Category { get; set; } - - [SugarColumn(ColumnDescription = "公告行为")] - public string Action { get; set; } - - [SugarColumn(ColumnDescription = "公告内容", ColumnDataType = StaticConfig.CodeFirst_BigString)] - public string Content { get; set; } - - public bool IsDeleted { get; } - public DateTime CreationTime { get; } - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } - public int OrderNum { get; set; } - public bool IsEnabled { get; set; } +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysAnnouncement", "系统公告表")] +public class AnnouncementEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "公告标题")] + public string Title { get; set; } + + [SugarColumn(ColumnDescription = "公告分类")] + public string Category { get; set; } + + [SugarColumn(ColumnDescription = "公告行为")] + public string Action { get; set; } + + [SugarColumn(ColumnDescription = "公告内容", ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string Content { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/ConfigEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/ConfigEntity.cs index 1a11029..598ea73 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/ConfigEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/ConfigEntity.cs @@ -1,34 +1,34 @@ -using Mapster; -using NPin.Framework.SqlSugarCore.Abstractions.Data; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("Config", "系统配置表")] -[SugarIndex($"index_{nameof(Key)}", nameof(Key), OrderByType.Asc, true)] -public class ConfigEntity : Entity, IEnabled, IOrderNum, ISoftDelete, IAuditedObject -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "配置名称")] - public string Name { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "配置键")] - public string Key { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "配置值")] - public string Value { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "配置描述")] - public string? Remark { get; set; } = string.Empty; - - public bool IsEnabled { get; set; } - public int OrderNum { get; set; } - public bool IsDeleted { get; } - public DateTime CreationTime { get; } - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } +using Mapster; +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysConfig", "系统配置表")] +[SugarIndex($"index_{nameof(Key)}", nameof(Key), OrderByType.Asc, true)] +public class ConfigEntity : Entity, IEnabled, IOrderNum, ISoftDelete, IAuditedObject +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "配置名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "配置键")] + public string Key { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "配置值")] + public string Value { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "配置描述")] + public string? Remark { get; set; } = string.Empty; + + public bool IsEnabled { get; set; } + public int OrderNum { get; set; } + public bool IsDeleted { get; } + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs index 23800f0..7c1b445 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/FileAggregateRoot.cs @@ -1,41 +1,41 @@ -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Data; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("File", "文件信息表")] -public class FileAggregateRoot : AggregateRoot, IAuditedObject -{ - [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "文件大小")] - public decimal FileSize { get; set; } - - [SugarColumn(ColumnDescription = "文件名称")] - public string FileName { get; set; } - - [SugarColumn(ColumnDescription = "文件后缀")] - public string FileExt { get; set; } - - [SugarColumn(ColumnDescription = "文件路径")] - public string FilePath { get; set; } - - public DateTime CreationTime { get; } - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } - - [SugarColumn(IsIgnore = true)] public override ExtraPropertyDictionary ExtraProperties { get; protected set; } - - public FileAggregateRoot() - { - } - - public FileAggregateRoot(Guid id) : base(id) - { - Id = id; - } +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysFile", "文件信息表")] +public class FileAggregateRoot : AggregateRoot, IAuditedObject +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "文件大小")] + public decimal FileSize { get; set; } + + [SugarColumn(ColumnDescription = "文件名称")] + public string FileName { get; set; } + + [SugarColumn(ColumnDescription = "文件后缀")] + public string FileExt { get; set; } + + [SugarColumn(ColumnDescription = "文件路径")] + public string FilePath { get; set; } + + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + + [SugarColumn(IsIgnore = true)] public override ExtraPropertyDictionary ExtraProperties { get; protected set; } + + public FileAggregateRoot() + { + } + + public FileAggregateRoot(Guid id) : base(id) + { + Id = id; + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/LoginLogEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/LoginLogEntity.cs index da55bc8..1365400 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/LoginLogEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/LoginLogEntity.cs @@ -1,81 +1,82 @@ -using System.Net; -using System.Net.Sockets; -using IPTools.Core; -using Microsoft.AspNetCore.Http; -using NPin.Framework.Core.Extensions; -using SqlSugar; -using UAParser; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("LoginLog", "登录日志表")] -public class LoginLogEntity : Entity, ICreationAuditedObject -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - public DateTime CreationTime { get; } - public Guid? CreatorId { get; } - - [SugarColumn(ColumnDescription = "登录用户")] - public string? LoginUser { get; set; } - - [SugarColumn(ColumnDescription = "登录用户ID")] - public Guid LoginUserId { get; set; } - - [SugarColumn(ColumnDescription = "登录地点")] - public string? LoginLocation { get; set; } - - [SugarColumn(ColumnDescription = "Ipv4")] - public string? LoginIPv4 { get; set; } - - [SugarColumn(ColumnDescription = "Ipv6")] - public string? LoginIPv6 { get; set; } - - [SugarColumn(ColumnDescription = "浏览器")] - public string? Browser { get; set; } - - [SugarColumn(ColumnDescription = "操作系统")] - public string? Os { get; set; } - - [SugarColumn(ColumnDescription = "登录信息")] - public string? LoginMsg { get; set; } - - public static LoginLogEntity GetInfoByHttpContext(HttpContext httpContext) - { - // var ipInfo = httpContext.GetRemoteIpInfo(); - string ipv4AddrStr = null; - string ipv6AddrStr = null; - var ipAddr = httpContext.GetClientIpAddress(); - if (ipAddr != null) - { - switch (ipAddr.AddressFamily) - { - case AddressFamily.InterNetwork: - ipv4AddrStr = ipAddr.ToString(); - break; - case AddressFamily.InterNetworkV6: - ipv6AddrStr = ipAddr.ToString(); - break; - } - } - - var location = IPAddress.IsLoopback(ipAddr) - ? new IpInfo { Province = "本地", City = "本机" } - : IpTool.Search(ipAddr.ToString()); - - var clientInfo = GetClientInfo(httpContext); - - return new LoginLogEntity - { - Browser = clientInfo.Device.Family, - Os = clientInfo.OS.ToString(), - LoginIPv4 = ipv4AddrStr, - LoginIPv6 = ipv6AddrStr, - LoginLocation = $"{location.Country}-{location.Province}-{location.City}" - }; - - ClientInfo GetClientInfo(HttpContext ctx) => Parser.GetDefault().Parse(ctx.GetUserAgent()); - } +using System.Net; +using System.Net.Sockets; +using IPTools.Core; +using Microsoft.AspNetCore.Http; +using NPin.Framework.Core.Extensions; +using SqlSugar; +using UAParser; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysLoginLog", "登录日志表")] +[SugarIndex($"index_{nameof(LoginUser)}", nameof(LoginUser), OrderByType.Asc)] +public class LoginLogEntity : Entity, ICreationAuditedObject +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + + [SugarColumn(ColumnDescription = "登录用户")] + public string? LoginUser { get; set; } + + [SugarColumn(ColumnDescription = "登录用户ID")] + public Guid LoginUserId { get; set; } + + [SugarColumn(ColumnDescription = "登录地点")] + public string? LoginLocation { get; set; } + + [SugarColumn(ColumnDescription = "Ipv4")] + public string? LoginIpv4 { get; set; } + + [SugarColumn(ColumnDescription = "Ipv6")] + public string? LoginIpv6 { get; set; } + + [SugarColumn(ColumnDescription = "浏览器")] + public string? Browser { get; set; } + + [SugarColumn(ColumnDescription = "操作系统")] + public string? Os { get; set; } + + [SugarColumn(ColumnDescription = "登录信息")] + public string? LoginMsg { get; set; } + + public static LoginLogEntity GetInfoByHttpContext(HttpContext httpContext) + { + // var ipInfo = httpContext.GetRemoteIpInfo(); + string ipv4AddrStr = null; + string ipv6AddrStr = null; + var ipAddr = httpContext.GetClientIpAddress(); + if (ipAddr != null) + { + switch (ipAddr.AddressFamily) + { + case AddressFamily.InterNetwork: + ipv4AddrStr = ipAddr.ToString(); + break; + case AddressFamily.InterNetworkV6: + ipv6AddrStr = ipAddr.ToString(); + break; + } + } + + var location = IPAddress.IsLoopback(ipAddr) + ? new IpInfo { Province = "本地", City = "本机" } + : IpTool.Search(ipAddr.ToString()); + + var clientInfo = GetClientInfo(httpContext); + + return new LoginLogEntity + { + Browser = clientInfo.Device.Family, + Os = clientInfo.OS.ToString(), + LoginIpv4 = ipv4AddrStr, + LoginIpv6 = ipv6AddrStr, + LoginLocation = $"{location.Country}-{location.Province}-{location.City}" + }; + + ClientInfo GetClientInfo(HttpContext ctx) => Parser.GetDefault().Parse(ctx.GetUserAgent()); + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs index 4e5a646..2c9391e 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/OrganizationEntity.cs @@ -1,46 +1,46 @@ -using NPin.Framework.SqlSugarCore.Abstractions.Data; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("Organization", "组织机构表")] -public class OrganizationEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled -{ - [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "组织机构名称")] - public string Name { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "组织机构编码")] - public string Code { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "描述")] - public string? Remark { get; set; } - - /// - /// 负责人ID - /// - public Guid LeaderId { get; set; } - - /// - /// 负责人名称,仅用户展示,不存储 - /// - [SugarColumn(IsIgnore = true)] - public string Leader { get; set; } - - /// - /// 父节点 ID - /// - public Guid ParentId { get; set; } - - public bool IsDeleted { get; } - public DateTime CreationTime { get; } = DateTime.Now; - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } - public int OrderNum { get; set; } - public bool IsEnabled { get; set; } +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysOrganization", "组织机构表")] +public class OrganizationEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "组织机构名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "组织机构编码")] + public string Code { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "描述")] + public string? Remark { get; set; } + + /// + /// 负责人ID + /// + public Guid LeaderId { get; set; } + + /// + /// 负责人名称,仅用户展示,不存储 + /// + [SugarColumn(IsIgnore = true)] + public string Leader { get; set; } + + /// + /// 父节点 ID + /// + public Guid ParentId { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs index d5df06e..7464309 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/PostEntity.cs @@ -1,30 +1,30 @@ -using NPin.Framework.SqlSugarCore.Abstractions.Data; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("Post", "岗位表")] -public class PostEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled -{ - [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "岗位编码")] - public string Code { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "岗位名称")] - public string Name { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "岗位描述")] - public string? Remark { get; set; } - - public bool IsDeleted { get; } - public DateTime CreationTime { get; } = DateTime.Now; - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } - public int OrderNum { get; set; } - public bool IsEnabled { get; set; } +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysPost", "岗位表")] +public class PostEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "岗位编码")] + public string Code { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "岗位名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "岗位描述")] + public string? Remark { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs index c0bbc3f..d1c3cdc 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/RoleEntity.cs @@ -1,42 +1,42 @@ -using NPin.Framework.SqlSugarCore.Abstractions.Data; -using NPin.Framework.Upms.Domain.Shared.Enums; -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("Role", "角色表")] -public class RoleEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled -{ - [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "角色代码")] - public string Code { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "角色名称")] - public string Name { get; set; } = string.Empty; - - [SugarColumn(ColumnDescription = "角色数据权限范围")] - public DataScopeEnum DataScope { get; set; } = DataScopeEnum.All; - - [SugarColumn(ColumnDescription = "描述")] - public string? Remark { get; set; } - - public bool IsDeleted { get; } - public DateTime CreationTime { get; } = DateTime.Now; - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } - public int OrderNum { get; set; } - public bool IsEnabled { get; set; } - - #region 导航 - - [Navigate(typeof(RoleOrganizationEntity), nameof(RoleOrganizationEntity.RoleId), - nameof(RoleOrganizationEntity.OrgId))] - public List OrganizationList { get; set; } - - #endregion +using NPin.Framework.SqlSugarCore.Abstractions.Data; +using NPin.Framework.Upms.Domain.Shared.Enums; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysRole", "角色表")] +public class RoleEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IEnabled +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "角色代码")] + public string Code { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "角色名称")] + public string Name { get; set; } = string.Empty; + + [SugarColumn(ColumnDescription = "角色数据权限范围")] + public DataScopeEnum DataScope { get; set; } = DataScopeEnum.All; + + [SugarColumn(ColumnDescription = "描述")] + public string? Remark { get; set; } + + public bool IsDeleted { get; } + public DateTime CreationTime { get; } = DateTime.Now; + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } + public int OrderNum { get; set; } + public bool IsEnabled { get; set; } + + #region 导航 + + [Navigate(typeof(RoleOrganizationEntity), nameof(RoleOrganizationEntity.RoleId), + nameof(RoleOrganizationEntity.OrgId))] + public List OrganizationList { get; set; } + + #endregion } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/RoleOrganizationEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/RoleOrganizationEntity.cs index 8bcf629..8daacc2 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/RoleOrganizationEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/RoleOrganizationEntity.cs @@ -1,16 +1,16 @@ -using SqlSugar; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("RelRoleOrganization", "角色-机构 关系表")] -public class RoleOrganizationEntity : Entity -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "角色ID")] - public Guid RoleId { get; set; } - - [SugarColumn(ColumnDescription = "机构ID")] - public Guid OrgId { get; set; } +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysRelRoleOrganization", "角色-机构 关系表")] +public class RoleOrganizationEntity : Entity +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "角色ID")] + public Guid RoleId { get; set; } + + [SugarColumn(ColumnDescription = "机构ID")] + public Guid OrgId { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs index 4b56d1b..d414f79 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserEntity.cs @@ -8,7 +8,8 @@ using Volo.Abp.Domain.Entities; namespace NPin.Framework.Upms.Domain.Entities; -[SugarTable("User", "用户表")] +[SugarTable("SysUser", "用户表")] +[SugarIndex($"index_{nameof(Username)}", nameof(Username), OrderByType.Asc)] public class UserEntity : Entity, ISoftDelete, IAuditedObject, IEnabled, IOrderNum { #region User diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs index feca0f1..4c32089 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserMetaEntity.cs @@ -1,24 +1,24 @@ -using SqlSugar; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("UserMetadata", "用户元数据表")] -public class UserMetaEntity : Entity, IAuditedObject -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - public Guid UserId; - - [SugarColumn(ColumnDescription = "元数据 键")] - public string Key { get; set; } - - [SugarColumn(ColumnDescription = "元数据 值")] - public string Value { get; set; } - - public DateTime CreationTime { get; } - public Guid? CreatorId { get; } - public DateTime? LastModificationTime { get; } - public Guid? LastModifierId { get; } +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysUserMetadata", "用户元数据表")] +public class UserMetaEntity : Entity, IAuditedObject +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + public Guid UserId; + + [SugarColumn(ColumnDescription = "元数据 键")] + public string Key { get; set; } + + [SugarColumn(ColumnDescription = "元数据 值")] + public string Value { get; set; } + + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + public DateTime? LastModificationTime { get; } + public Guid? LastModifierId { get; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs index 724b8c2..98bdfb2 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserOrganizationEntity.cs @@ -1,16 +1,16 @@ -using SqlSugar; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("RelUserOrganization", "用户-组织机构 关系表")] -public class UserOrganizationEntity : Entity -{ - [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "用户ID")] - public Guid UserId { get; set; } - - [SugarColumn(ColumnDescription = "组织机构ID")] - public Guid OrganizationId { get; set; } +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysRelUserOrganization", "用户-组织机构 关系表")] +public class UserOrganizationEntity : Entity +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "用户ID")] + public Guid UserId { get; set; } + + [SugarColumn(ColumnDescription = "组织机构ID")] + public Guid OrganizationId { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs index 3ab6167..36339b6 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserPostEntity.cs @@ -1,17 +1,17 @@ -using SqlSugar; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("RelUserPost","用户-岗位 关系表")] -public class UserPostEntity: Entity -{ - [SugarColumn(IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "用户ID")] - public Guid UserId { get; set; } - - [SugarColumn(ColumnDescription = "岗位ID")] - public Guid PostId { get; set; } +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysRelUserPost","用户-岗位 关系表")] +public class UserPostEntity: Entity +{ + [SugarColumn(IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "用户ID")] + public Guid UserId { get; set; } + + [SugarColumn(ColumnDescription = "岗位ID")] + public Guid PostId { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs b/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs index a5c8272..cd97382 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Entities/UserRoleEntity.cs @@ -1,17 +1,17 @@ -using SqlSugar; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.Entities; - -[SugarTable("RelUserRole", "用户-角色 关系表")] -public class UserRoleEntity: Entity -{ - [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "角色ID")] - public Guid RoleId { get; set; } - - [SugarColumn(ColumnDescription = "用户ID")] - public Guid UserId { get; set; } +using SqlSugar; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.Entities; + +[SugarTable("SysRelUserRole", "用户-角色 关系表")] +public class UserRoleEntity: Entity +{ + [SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")] + public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "角色ID")] + public Guid RoleId { get; set; } + + [SugarColumn(ColumnDescription = "用户ID")] + public Guid UserId { get; set; } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Managers/SmsManager.cs b/module/upms/NPin.Framework.Upms.Domain/Managers/SmsManager.cs index 2c698d1..7e648c6 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Managers/SmsManager.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Managers/SmsManager.cs @@ -1,129 +1,78 @@ -using AlibabaCloud.OpenApiClient.Models; -using AlibabaCloud.SDK.Dysmsapi20170525; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using NPin.Framework.Upms.Domain.Repositories; -using NPin.Framework.Upms.Domain.Shared.Enums; -using NPin.Framework.Upms.Domain.Shared.Model; -using NPin.Framework.Upms.Domain.Shared.Options; -using TencentCloud.Common; -using TencentCloud.Common.Profile; -using TencentCloud.Sms.V20210111; -using TencentCloud.Sms.V20210111.Models; -using Volo.Abp.Caching; -using Volo.Abp.Domain.Services; - -namespace NPin.Framework.Upms.Domain.Managers; - -public class SmsManager : DomainService, ISms -{ - private ILogger _logger; - private IConfigRepository _configRepository; - private IDistributedCache _cache; - - public SmsManager(ILogger logger, IConfigRepository configRepository) - { - _logger = logger; - _configRepository = configRepository; - } - - public async Task SendSmsAsync(SmsTypeEnum smsType, string phoneNumbers, object templateParam) - { - - try - { - var smsSettings = SmsOptions.Config[smsType]; - if (!smsSettings.Enabled) - { - return; - } - - switch (smsSettings.Provider) - { - case SmsProviderEnum.Aliyun: - await SendAliyunSmsAsync(smsSettings, phoneNumbers, templateParam); - break; - case SmsProviderEnum.Tencent: - await SendTencentSmsAsync(smsSettings, phoneNumbers, templateParam); - break; - default: - throw new Exception("未实现该服务提供商"); - } - } - catch (Exception ex) - { - _logger.LogError(ex, $"短信发送失败: {ex.Message}"); - throw new UserFriendlyException($"短信发送失败: {ex.Message}"); - } - } - - private async Task SendTencentSmsAsync(SmsSettings settings, string phoneNumbers, - object templateParam) - { - var client = SmsClientProvider.CreateClient(TencentOptions, settings); - - var sendSmsRequest = new SendSmsRequest - { - PhoneNumberSet = phoneNumbers.Split(','), - SignName = settings.SignName, - TemplateId = settings.TemplateCode, - TemplateParamSet = templateParam as string[] - }; - - var response = await client.SendSms(sendSmsRequest); - } - - private async Task SendAliyunSmsAsync(SmsSettings settings, string phoneNumbers, - object templateParam) - { - var client = SmsClientProvider.CreateClient(AliyunOptions, settings); - - var sendSmsRequest = new AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest - { - PhoneNumbers = phoneNumbers, - SignName = settings.SignName, - TemplateCode = settings.TemplateCode, - TemplateParam = JsonConvert.SerializeObject(templateParam) - }; - - var response = await client.SendSmsAsync(sendSmsRequest); - } -} - -public static class SmsClientProvider -{ - public static Client CreateClient(AliyunOptions options, SmsSettings settings) - { - var config = new Config() - { - AccessKeyId = options.AccessKeyId, - AccessKeySecret = options.AccessKeySecret, - Endpoint = settings.Endpoint, - RegionId = settings.RegionId, - }; - - return new Client(config); - } - - public static SmsClient CreateClient(TencentOptions options, SmsSettings settings) - { - var cred = new Credential - { - SecretId = options.SecretId, - SecretKey = options.SecretKey, - }; - - var httpProfile = new HttpProfile - { - Endpoint = settings.Endpoint, - }; - - var clientProfile = new ClientProfile() - { - HttpProfile = httpProfile - }; - - - return new SmsClient(cred, settings.RegionId, clientProfile); - } +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using NPin.Framework.SettingManagement.Domain; +using NPin.Framework.Upms.Domain.Settings; +using NPin.Framework.Upms.Domain.Shared.Consts; +using NPin.Framework.Upms.Domain.Shared.Enums; +using NPin.Framework.Upms.Domain.Shared.Model; +using NPin.Framework.Upms.Domain.Sms; +using Volo.Abp.Domain.Services; + +namespace NPin.Framework.Upms.Domain.Managers; + +public class SmsManager : DomainService +{ + private readonly ILogger _logger; + + private readonly ISettingManager _settingManager; + + private readonly IEnumerable _smsProviders; + + public SmsManager(ILogger logger, ISettingManager settingManager, IEnumerable smsProviders) + { + _logger = logger; + _settingManager = settingManager; + _smsProviders = smsProviders; + } + + public async Task GetSmsConfigModelAsync() + { + var configJson = await _settingManager.GetOrNullUpmsAsync(ConfigConst.SmsConfigModelKey); + var settingsJson = await _settingManager.GetOrNullUpmsAsync(ConfigConst.SmsSettingsKey); + var providersJson = await _settingManager.GetOrNullUpmsAsync(ConfigConst.SmsProvidersKey); + var templateJson = await _settingManager.GetOrNullUpmsAsync(ConfigConst.SmsTemplatesKey); + + var ret = JsonConvert.DeserializeObject(configJson ?? string.Empty) ?? new SmsConfigModel(); + + ret.Settings = + JsonConvert.DeserializeObject>(settingsJson ?? string.Empty) ?? + new Dictionary(); + + ret.Providers = JsonConvert.DeserializeObject>(providersJson ?? string.Empty) ?? []; + ret.Templates = JsonConvert.DeserializeObject>(templateJson ?? string.Empty) ?? []; + + return ret; + } + + public async Task SendSmsAsync(SmsTypeEnum smsType, string phoneNumbers, object templateParam) + { + try + { + var smsConfig = await GetSmsConfigModelAsync(); + if (!smsConfig.Enabled) + { + throw new UserFriendlyException("短信服务未启用,无法发送短信。"); + } + + var settings = smsConfig.GetSetting(smsType); + if (settings is null) + { + throw new UserFriendlyException("未找到对应短信类型,无法发送短信。"); + } + + var providerConfig = smsConfig.GetProvider(settings); + var provider = _smsProviders.FirstOrDefault(i => i.ProviderType == providerConfig.ProviderType); + if (provider is null) + { + throw new NotImplementedException("未实现该方式的短信控制器"); + } + + await provider.SendSmsAsync(smsConfig, settings, phoneNumbers, templateParam); + } + catch (Exception ex) + { + _logger.LogError(ex, $"短信发送失败: {ex.Message}"); + throw new UserFriendlyException($"短信发送失败: {ex.Message}"); + } + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/NPin.Framework.Upms.Domain.csproj b/module/upms/NPin.Framework.Upms.Domain/NPin.Framework.Upms.Domain.csproj index 5d8985d..5ab2e7f 100644 --- a/module/upms/NPin.Framework.Upms.Domain/NPin.Framework.Upms.Domain.csproj +++ b/module/upms/NPin.Framework.Upms.Domain/NPin.Framework.Upms.Domain.csproj @@ -3,6 +3,7 @@ + diff --git a/module/upms/NPin.Framework.Upms.Domain/NPinFrameworkUpmsDomainModule.cs b/module/upms/NPin.Framework.Upms.Domain/NPinFrameworkUpmsDomainModule.cs index 6f41c0c..c4342d4 100644 --- a/module/upms/NPin.Framework.Upms.Domain/NPinFrameworkUpmsDomainModule.cs +++ b/module/upms/NPin.Framework.Upms.Domain/NPinFrameworkUpmsDomainModule.cs @@ -1,32 +1,40 @@ -using Microsoft.Extensions.DependencyInjection; -using NPin.Framework.Caching.FreeRedis; -using NPin.Framework.Upms.Domain.Authorization; -using NPin.Framework.Upms.Domain.OperLog; -using NPin.Framework.Upms.Domain.Shared; -using Volo.Abp.AspNetCore.SignalR; -using Volo.Abp.Caching; -using Volo.Abp.Domain; - -namespace NPin.Framework.Upms.Domain; - -[DependsOn( - typeof(NPinFrameworkUpmsDomainSharedModule), - typeof(NPinFrameworkCachingFreeRedisModule), - // Abp - typeof(AbpAspNetCoreSignalRModule), - typeof(AbpDddDomainModule), - typeof(AbpCachingModule) -)] -public class NPinFrameworkUpmsDomainModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - var services = context.Services; - var configuration = services.GetConfiguration(); - services.AddControllers(opts => - { - opts.Filters.Add(); - opts.Filters.Add(); - }); - } +using Microsoft.Extensions.DependencyInjection; +using NPin.Framework.Caching.FreeRedis; +using NPin.Framework.SettingManagement.Domain; +using NPin.Framework.SettingManagement.Domain.Options; +using NPin.Framework.Upms.Domain.Authorization; +using NPin.Framework.Upms.Domain.OperLog; +using NPin.Framework.Upms.Domain.Settings; +using NPin.Framework.Upms.Domain.Shared; +using Volo.Abp.AspNetCore.SignalR; +using Volo.Abp.Caching; +using Volo.Abp.Domain; + +namespace NPin.Framework.Upms.Domain; + +[DependsOn( + typeof(NPinFrameworkUpmsDomainSharedModule), + typeof(NPinFrameworkCachingFreeRedisModule), + // Settings + typeof(NPinFrameworkSettingManagementDomainModule), + // Abp + typeof(AbpAspNetCoreSignalRModule), + typeof(AbpDddDomainModule), + typeof(AbpCachingModule) +)] +public class NPinFrameworkUpmsDomainModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var services = context.Services; + var configuration = services.GetConfiguration(); + services.AddControllers(opts => + { + opts.Filters.Add(); + opts.Filters.Add(); + }); + + // 添加Upms模块的设置提供者 + Configure(opt => { opt.Providers.Add(); }); + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/OperLog/OperationLogEntity.cs b/module/upms/NPin.Framework.Upms.Domain/OperLog/OperationLogEntity.cs index 246adab..367865c 100644 --- a/module/upms/NPin.Framework.Upms.Domain/OperLog/OperationLogEntity.cs +++ b/module/upms/NPin.Framework.Upms.Domain/OperLog/OperationLogEntity.cs @@ -1,86 +1,84 @@ -using System.Net; -using System.Net.Sockets; -using IPTools.Core; -using Microsoft.AspNetCore.Http; -using NPin.Framework.Core.Extensions; -using NPin.Framework.Upms.Domain.Entities; -using NPin.Framework.Upms.Domain.Shared.OperLog; -using SqlSugar; -using UAParser; -using Volo.Abp.Auditing; -using Volo.Abp.Domain.Entities; - -namespace NPin.Framework.Upms.Domain.OperLog; - -[SugarTable("OperationLog", "操作日志记录表")] -public class OperationLogEntity: Entity, ICreationAuditedObject -{ - [SugarColumn(IsPrimaryKey = true)] - public override Guid Id { get; protected set; } - - [SugarColumn(ColumnDescription = "日志标题")] - public string? Title { get; set; } - - [SugarColumn(ColumnDescription = "操作类型")] - public OperTypeEnum OperType { get; set; } - - [SugarColumn(ColumnDescription = "请求方式")] - public string? RequestMethod { get; set; } - - [SugarColumn(ColumnDescription = "操作者")] - public string? OperUser { get; set; } - - [SugarColumn(ColumnDescription = "操作者Ipv4")] - public string? OperIPv4 { get; set; } - - [SugarColumn(ColumnDescription = "操作者Ipv6")] - public string? OperIPv6 { get; set; } - - [SugarColumn(ColumnDescription = "操作地点")] - public string? OperLocation { get; set; } - - [SugarColumn(ColumnDescription = "操作方法")] - public string? Method { get; set; } - - [SugarColumn(ColumnDescription = "请求参数")] - public string? RequestParam { get; set; } - - [SugarColumn(ColumnDescription = "请求结果", Length = 9999)] - public string? RequestResult { get; set; } - - public DateTime CreationTime { get; } - public Guid? CreatorId { get; } - - public static OperationLogEntity GetInfoByHttpContext(HttpContext httpContext) - { - // var ipInfo = httpContext.GetRemoteIpInfo(); - string ipv4AddrStr = null; - string ipv6AddrStr = null; - IpInfo info = new IpInfo { Province = "本地", City = "本机" }; - - var ipAddr = httpContext.GetClientIpAddress(); - if (ipAddr != null) - { - switch (ipAddr.AddressFamily) - { - case AddressFamily.InterNetwork: - ipv4AddrStr = ipAddr.ToString(); - break; - case AddressFamily.InterNetworkV6: - ipv6AddrStr = ipAddr.ToString(); - break; - } - - if (!IPAddress.IsLoopback(ipAddr)) - { - info = IpTool.Search(ipAddr.ToString()); - } - } - return new OperationLogEntity - { - OperIPv4 = ipv4AddrStr, - OperIPv6 = ipv6AddrStr, - OperLocation = $"{info.Country}-{info.Province}-{info.City}" - }; - } +using System.Net; +using System.Net.Sockets; +using IPTools.Core; +using Microsoft.AspNetCore.Http; +using NPin.Framework.Core.Extensions; +using NPin.Framework.Upms.Domain.Shared.OperLog; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; + +namespace NPin.Framework.Upms.Domain.OperLog; + +[SugarTable("SysOperationLog", "操作日志记录表")] +public class OperationLogEntity : Entity, ICreationAuditedObject +{ + [SugarColumn(IsPrimaryKey = true)] public override Guid Id { get; protected set; } + + [SugarColumn(ColumnDescription = "日志标题")] + public string? Title { get; set; } + + [SugarColumn(ColumnDescription = "操作类型")] + public OperTypeEnum OperType { get; set; } + + [SugarColumn(ColumnDescription = "请求方式")] + public string? RequestMethod { get; set; } + + [SugarColumn(ColumnDescription = "操作者")] + public string? OperUser { get; set; } + + [SugarColumn(ColumnDescription = "操作者Ipv4")] + public string? OperIPv4 { get; set; } + + [SugarColumn(ColumnDescription = "操作者Ipv6")] + public string? OperIPv6 { get; set; } + + [SugarColumn(ColumnDescription = "操作地点")] + public string? OperLocation { get; set; } + + [SugarColumn(ColumnDescription = "操作方法")] + public string? Method { get; set; } + + [SugarColumn(ColumnDescription = "请求参数")] + public string? RequestParam { get; set; } + + [SugarColumn(ColumnDescription = "请求结果", Length = 9999)] + public string? RequestResult { get; set; } + + public DateTime CreationTime { get; } + public Guid? CreatorId { get; } + + public static OperationLogEntity GetInfoByHttpContext(HttpContext httpContext) + { + // var ipInfo = httpContext.GetRemoteIpInfo(); + string ipv4AddrStr = null; + string ipv6AddrStr = null; + IpInfo info = new IpInfo { Province = "本地", City = "本机" }; + + var ipAddr = httpContext.GetClientIpAddress(); + if (ipAddr != null) + { + switch (ipAddr.AddressFamily) + { + case AddressFamily.InterNetwork: + ipv4AddrStr = ipAddr.ToString(); + break; + case AddressFamily.InterNetworkV6: + ipv6AddrStr = ipAddr.ToString(); + break; + } + + if (!IPAddress.IsLoopback(ipAddr)) + { + info = IpTool.Search(ipAddr.ToString()); + } + } + + return new OperationLogEntity + { + OperIPv4 = ipv4AddrStr, + OperIPv6 = ipv6AddrStr, + OperLocation = $"{info.Country}-{info.Province}-{info.City}" + }; + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagementProvider.cs b/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagementProvider.cs new file mode 100644 index 0000000..e352dc2 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagementProvider.cs @@ -0,0 +1,17 @@ +using NPin.Framework.SettingManagement.Domain; +using NPin.Framework.SettingManagement.Domain.Store; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.Upms.Domain.Settings; + +public class UpmsSettingManagementProvider: SettingManagementProvider, ITransientDependency +{ + public const string ProviderName = "Upms"; + + public override string Name => ProviderName; + + public UpmsSettingManagementProvider(ISettingManagementStore settingManagementStore) : base(settingManagementStore) + { + } + +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagerExtensions.cs b/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagerExtensions.cs new file mode 100644 index 0000000..891e93a --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsSettingManagerExtensions.cs @@ -0,0 +1,23 @@ +using NPin.Framework.SettingManagement.Domain; +using Volo.Abp.Settings; + +namespace NPin.Framework.Upms.Domain.Settings; + +public static class UpmsSettingManagerExtensions +{ + public static Task GetOrNullUpmsAsync(this ISettingManager settingManager, string name, + bool fallback = true) + { + return settingManager.GetOrNullAsync(name, UpmsSettingManagementProvider.ProviderName, null, fallback); + } + + public static Task> GetAllUpmsAsync(this ISettingManager settingManager, bool fallback = true) + { + return settingManager.GetAllAsync(UpmsSettingManagementProvider.ProviderName, null, fallback); + } + + public static Task SetUpmsAsync(this ISettingManager settingManager, string name, string value) + { + return settingManager.SetAsync(name, value, UpmsSettingManagementProvider.ProviderName, null); + } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsStaticSettingProvider.cs b/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsStaticSettingProvider.cs new file mode 100644 index 0000000..087b429 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Settings/UpmsStaticSettingProvider.cs @@ -0,0 +1,20 @@ +using NPin.Framework.Upms.Domain.Shared.Consts; +using Volo.Abp.Settings; + +namespace NPin.Framework.Upms.Domain.Settings; + +public class UpmsStaticSettingProvider: SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + DefineSmsSettingDefinitions(context); + } + + private void DefineSmsSettingDefinitions(ISettingDefinitionContext context) + { + context.Add(new SettingDefinition(ConfigConst.SmsConfigModelKey)); + context.Add(new SettingDefinition(ConfigConst.SmsProvidersKey)); + context.Add(new SettingDefinition(ConfigConst.SmsSettingsKey)); + context.Add(new SettingDefinition(ConfigConst.SmsTemplatesKey)); + } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Sms/Handler/AliyunSmsHandler.cs b/module/upms/NPin.Framework.Upms.Domain/Sms/Handler/AliyunSmsHandler.cs new file mode 100644 index 0000000..f72c861 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Sms/Handler/AliyunSmsHandler.cs @@ -0,0 +1,54 @@ +using AlibabaCloud.OpenApiClient.Models; +using AlibabaCloud.SDK.Dysmsapi20170525; +using AlibabaCloud.SDK.Dysmsapi20170525.Models; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using NPin.Framework.Upms.Domain.Shared.Enums; +using NPin.Framework.Upms.Domain.Shared.Model; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.Upms.Domain.Sms.Handler; + +public class AliyunSmsHandler : ISms, ISingletonDependency +{ + private readonly ILogger _logger; + + public AliyunSmsHandler(ILogger logger) + { + _logger = logger; + } + + public SmsProviderTypeEnum ProviderType => SmsProviderTypeEnum.Aliyun; + + public async Task SendSmsAsync(SmsConfigModel config, SmsSettings settings, string phoneNumbers, + object templateParam) + { + var client = CreateClient(config.GetProvider(settings)); + var template = config.GetTemplate(settings); + + var sendSmsRequest = new SendSmsRequest + { + PhoneNumbers = phoneNumbers, + SignName = template.SignName, + TemplateCode = template.TemplateCode, + TemplateParam = JsonConvert.SerializeObject(templateParam) + }; + + var response = await client.SendSmsAsync(sendSmsRequest); + + // TODO 判断结果 + _logger.LogDebug(response.ToString()); + } + + private Client CreateClient(SmsProvider provider) + { + var config = new Config() + { + AccessKeyId = provider.AccessKeyId, + AccessKeySecret = provider.AccessKeySecret, + Endpoint = provider.Endpoint, + RegionId = provider.Region, + }; + return new Client(config); + } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Sms/Handler/TencentSmsHandler.cs b/module/upms/NPin.Framework.Upms.Domain/Sms/Handler/TencentSmsHandler.cs new file mode 100644 index 0000000..d3a7de8 --- /dev/null +++ b/module/upms/NPin.Framework.Upms.Domain/Sms/Handler/TencentSmsHandler.cs @@ -0,0 +1,64 @@ +using Microsoft.Extensions.Logging; +using NPin.Framework.Upms.Domain.Shared.Enums; +using NPin.Framework.Upms.Domain.Shared.Model; +using TencentCloud.Common; +using TencentCloud.Common.Profile; +using TencentCloud.Sms.V20210111; +using TencentCloud.Sms.V20210111.Models; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.Upms.Domain.Sms.Handler; + +public class TencentSmsHandler : ISms, ISingletonDependency +{ + private readonly ILogger _logger; + + public TencentSmsHandler(ILogger logger) + { + _logger = logger; + } + + public SmsProviderTypeEnum ProviderType => SmsProviderTypeEnum.Tencent; + + public async Task SendSmsAsync(SmsConfigModel config, SmsSettings settings, string phoneNumbers, + object templateParam) + { + var client = CreateClient(config.GetProvider(settings)); + var template = config.GetTemplate(settings); + + var sendSmsRequest = new SendSmsRequest + { + PhoneNumberSet = phoneNumbers.Split(','), + SignName = template.SignName, + TemplateId = template.TemplateCode, + TemplateParamSet = templateParam as string[] + }; + + var response = await client.SendSms(sendSmsRequest); + + // TODO 判断结果 + _logger.LogDebug(response.ToString()); + } + + private SmsClient CreateClient(SmsProvider provider) + { + var cred = new Credential + { + SecretId = provider.AccessKeyId, + SecretKey = provider.AccessKeySecret, + }; + + var httpProfile = new HttpProfile + { + Endpoint = provider.Endpoint, + }; + + var clientProfile = new ClientProfile() + { + HttpProfile = httpProfile + }; + + + return new SmsClient(cred, provider.Region, clientProfile); + } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.Domain/Sms/ISms.cs b/module/upms/NPin.Framework.Upms.Domain/Sms/ISms.cs index 0ac1525..c65eade 100644 --- a/module/upms/NPin.Framework.Upms.Domain/Sms/ISms.cs +++ b/module/upms/NPin.Framework.Upms.Domain/Sms/ISms.cs @@ -1,11 +1,17 @@ -using NPin.Framework.Upms.Domain.Shared.Enums; - -namespace NPin.Framework.Upms.Domain.Managers; - -/// -/// 短信接口 -/// -public interface ISms -{ - Task SendSmsAsync(SmsTypeEnum smsType, string phoneNumbers, object templateParam); +using NPin.Framework.Upms.Domain.Shared.Enums; +using NPin.Framework.Upms.Domain.Shared.Model; + +namespace NPin.Framework.Upms.Domain.Sms; + +/// +/// 统一短信接口 +/// +public interface ISms +{ + /// + /// 短信提供商类型 + /// + SmsProviderTypeEnum ProviderType { get; } + + Task SendSmsAsync(SmsConfigModel config, SmsSettings settings, string phoneNumbers, object templateParam); } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.SqlSugarCore/DataSeeds/SmsConfigDataSeed.cs b/module/upms/NPin.Framework.Upms.SqlSugarCore/DataSeeds/SmsConfigDataSeed.cs new file mode 100644 index 0000000..9c4c2ff --- /dev/null +++ b/module/upms/NPin.Framework.Upms.SqlSugarCore/DataSeeds/SmsConfigDataSeed.cs @@ -0,0 +1,46 @@ +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using NPin.Framework.SettingManagement.Domain; +using NPin.Framework.Upms.Domain.Managers; +using NPin.Framework.Upms.Domain.Settings; +using NPin.Framework.Upms.Domain.Shared.Consts; +using NPin.Framework.Upms.Domain.Shared.Model; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.Upms.SqlSugarCore.DataSeeds; + +public class SmsConfigDataSeed : IDataSeedContributor, ITransientDependency +{ + private readonly ILogger _logger; + + private readonly ISettingManager _settingManager; + + public SmsConfigDataSeed(ILogger logger, ISettingManager settingManager) + { + _logger = logger; + _settingManager = settingManager; + } + + public async Task SeedAsync(DataSeedContext context) + { + var configJson = await _settingManager.GetOrNullUpmsAsync(ConfigConst.SmsConfigModelKey); + if (!string.IsNullOrEmpty(configJson)) + { + return; + } + + var configModel = new SmsConfigModel + { + Enabled = false, + Providers = [], + Settings = [], + Templates = [] + }; + + await _settingManager.SetUpmsAsync(ConfigConst.SmsConfigModelKey, JsonConvert.SerializeObject(configModel)); + await _settingManager.SetUpmsAsync(ConfigConst.SmsSettingsKey, JsonConvert.SerializeObject(configModel.Settings)); + await _settingManager.SetUpmsAsync(ConfigConst.SmsProvidersKey, JsonConvert.SerializeObject(configModel.Providers)); + await _settingManager.SetUpmsAsync(ConfigConst.SmsTemplatesKey, JsonConvert.SerializeObject(configModel.Templates)); + } +} \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.SqlSugarCore/NPin.Framework.Upms.SqlSugarCore.csproj b/module/upms/NPin.Framework.Upms.SqlSugarCore/NPin.Framework.Upms.SqlSugarCore.csproj index 38f9347..7a34565 100644 --- a/module/upms/NPin.Framework.Upms.SqlSugarCore/NPin.Framework.Upms.SqlSugarCore.csproj +++ b/module/upms/NPin.Framework.Upms.SqlSugarCore/NPin.Framework.Upms.SqlSugarCore.csproj @@ -1,10 +1,11 @@ - - - - - - - - - - + + + + + + + + + + + diff --git a/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinFrameworkUpmsSqlSugarCoreModule.cs b/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinFrameworkUpmsSqlSugarCoreModule.cs index 6dec149..782b939 100644 --- a/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinFrameworkUpmsSqlSugarCoreModule.cs +++ b/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinFrameworkUpmsSqlSugarCoreModule.cs @@ -1,19 +1,22 @@ -using NPin.Framework.Mapster; -using NPin.Framework.SqlSugarCore; -using NPin.Framework.Upms.Domain; - -namespace NPin.Framework.Upms.SqlSugarCore; - -[DependsOn( - typeof(NPinFrameworkUpmsDomainModule), - // framework - typeof(NPinFrameworkMapsterModule), - typeof(NPinFrameworkSqlSugarCoreModule) -)] -public class NPinFrameworkUpmsSqlSugarCoreModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - - } +using NPin.Framework.Mapster; +using NPin.Framework.SettingManagement.SqlSugarCore; +using NPin.Framework.SqlSugarCore; +using NPin.Framework.Upms.Domain; + +namespace NPin.Framework.Upms.SqlSugarCore.Repositories; + +[DependsOn( + typeof(NPinFrameworkUpmsDomainModule), + // settings + typeof(NPinFrameworkSettingManagementSqlSugarCoreModule), + // framework + typeof(NPinFrameworkMapsterModule), + typeof(NPinFrameworkSqlSugarCoreModule) +)] +public class NPinFrameworkUpmsSqlSugarCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinUpmsDbContext.cs b/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinUpmsDbContext.cs index de4af47..82226a5 100644 --- a/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinUpmsDbContext.cs +++ b/module/upms/NPin.Framework.Upms.SqlSugarCore/NPinUpmsDbContext.cs @@ -1,49 +1,49 @@ -using NPin.Framework.SqlSugarCore; -using NPin.Framework.Upms.Domain.Authorization; -using NPin.Framework.Upms.Domain.Shared.Consts; -using SqlSugar; -using Volo.Abp.DependencyInjection; - -namespace NPin.Framework.Upms.SqlSugarCore; - -public class NPinUpmsDbContext : SqlSugarDbContext -{ - public NPinUpmsDbContext(IAbpLazyServiceProvider lazyServiceProvider) : base(lazyServiceProvider) - { - } - - protected override void CustomDataFilter(ISqlSugarClient sqlSugarClient) - { - if (DataFilter.IsEnabled()) - { - DataPermissionFilter(sqlSugarClient); - } - - base.CustomDataFilter(sqlSugarClient); - } - - /// - /// 数据权限过滤 - /// - /// - protected void DataPermissionFilter(ISqlSugarClient sqlSugarClient) - { - // 当前无登录用户,无需过滤 - if (CurrentUser.Id == null) return; - - // 管理员角色 不进行过滤 - if (CurrentUser.UserName.Equals(UserConst.Admin) || - CurrentUser.Roles.Any(r => r.Equals(UserConst.AdminRoleCode))) - { - return; - } - - // var expUser = Expressionable.Create<>(); - // var expRole = Expressionable.Create<>(); - - // 无岗位 or 无角色 只能看自己 - - - // sqlSugarClient.QueryFilter.AddTableFilter() - } +using NPin.Framework.SqlSugarCore; +using NPin.Framework.Upms.Domain.Authorization; +using NPin.Framework.Upms.Domain.Shared.Consts; +using SqlSugar; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.Upms.SqlSugarCore.Repositories; + +public class NPinUpmsDbContext : SqlSugarDbContext +{ + public NPinUpmsDbContext(IAbpLazyServiceProvider lazyServiceProvider) : base(lazyServiceProvider) + { + } + + protected override void CustomDataFilter(ISqlSugarClient sqlSugarClient) + { + if (DataFilter.IsEnabled()) + { + DataPermissionFilter(sqlSugarClient); + } + + base.CustomDataFilter(sqlSugarClient); + } + + /// + /// 数据权限过滤 + /// + /// + protected void DataPermissionFilter(ISqlSugarClient sqlSugarClient) + { + // 当前无登录用户,无需过滤 + if (CurrentUser.Id == null) return; + + // 管理员角色 不进行过滤 + if (CurrentUser.UserName.Equals(UserConst.Admin) || + CurrentUser.Roles.Any(r => r.Equals(UserConst.AdminRoleCode))) + { + return; + } + + // var expUser = Expressionable.Create<>(); + // var expRole = Expressionable.Create<>(); + + // 无岗位 or 无角色 只能看自己 + + + // sqlSugarClient.QueryFilter.AddTableFilter() + } } \ No newline at end of file diff --git a/module/upms/NPin.Framework.Upms.SqlSugarCore/ConfigRepository.cs b/module/upms/NPin.Framework.Upms.SqlSugarCore/Repositories/ConfigRepository.cs similarity index 91% rename from module/upms/NPin.Framework.Upms.SqlSugarCore/ConfigRepository.cs rename to module/upms/NPin.Framework.Upms.SqlSugarCore/Repositories/ConfigRepository.cs index 2d6de93..9a7e3d9 100644 --- a/module/upms/NPin.Framework.Upms.SqlSugarCore/ConfigRepository.cs +++ b/module/upms/NPin.Framework.Upms.SqlSugarCore/Repositories/ConfigRepository.cs @@ -1,30 +1,30 @@ -using Newtonsoft.Json; -using NPin.Framework.SqlSugarCore.Abstractions; -using NPin.Framework.SqlSugarCore.Repositories; -using NPin.Framework.Upms.Domain.Entities; -using NPin.Framework.Upms.Domain.Repositories; -using Volo.Abp.DependencyInjection; - -namespace NPin.Framework.Upms.SqlSugarCore; - -public class ConfigRepository : SqlSugarRepository, IConfigRepository, ITransientDependency -{ - public ConfigRepository(ISugarDbContextProvider sugarDbContextProvider) : base( - sugarDbContextProvider) - { - } - - public async Task GetSingleByKeyAsync(string key) where TDestination : new() - { - var config = await DbQueryable - .Where(e => e.Key.Equals(key)) - .FirstAsync(); - if (config is null) - { - return new TDestination(); - } - - var ret = JsonConvert.DeserializeObject(config.Value); - return ret ?? new TDestination(); - } +using Newtonsoft.Json; +using NPin.Framework.SqlSugarCore.Abstractions; +using NPin.Framework.SqlSugarCore.Repositories; +using NPin.Framework.Upms.Domain.Entities; +using NPin.Framework.Upms.Domain.Repositories; +using Volo.Abp.DependencyInjection; + +namespace NPin.Framework.Upms.SqlSugarCore.Repositories; + +public class ConfigRepository : SqlSugarRepository, IConfigRepository, ITransientDependency +{ + public ConfigRepository(ISugarDbContextProvider sugarDbContextProvider) : base( + sugarDbContextProvider) + { + } + + public async Task GetSingleByKeyAsync(string key) where TDestination : new() + { + var config = await DbQueryable + .Where(e => e.Key.Equals(key)) + .FirstAsync(); + if (config is null) + { + return new TDestination(); + } + + var ret = JsonConvert.DeserializeObject(config.Value); + return ret ?? new TDestination(); + } } \ No newline at end of file diff --git a/src/NPin.SqlSugarCore/NPinDbContext.cs b/src/NPin.SqlSugarCore/NPinDbContext.cs index bd91538..591742e 100644 --- a/src/NPin.SqlSugarCore/NPinDbContext.cs +++ b/src/NPin.SqlSugarCore/NPinDbContext.cs @@ -1,11 +1,11 @@ -using NPin.Framework.Upms.SqlSugarCore; -using Volo.Abp.DependencyInjection; - -namespace NPin.SqlSugarCore; - -public class NPinDbContext: NPinUpmsDbContext -{ - public NPinDbContext(IAbpLazyServiceProvider lazyServiceProvider) : base(lazyServiceProvider) - { - } +using NPin.Framework.Upms.SqlSugarCore.Repositories; +using Volo.Abp.DependencyInjection; + +namespace NPin.SqlSugarCore; + +public class NPinDbContext: NPinUpmsDbContext +{ + public NPinDbContext(IAbpLazyServiceProvider lazyServiceProvider) : base(lazyServiceProvider) + { + } } \ No newline at end of file diff --git a/src/NPin.SqlSugarCore/NPinSqlSugarCoreModule.cs b/src/NPin.SqlSugarCore/NPinSqlSugarCoreModule.cs index 3af713a..3617f8c 100644 --- a/src/NPin.SqlSugarCore/NPinSqlSugarCoreModule.cs +++ b/src/NPin.SqlSugarCore/NPinSqlSugarCoreModule.cs @@ -1,29 +1,29 @@ -using NPin.Domain; -using NPin.Framework.AuditLogging.SqlSugarCore; -using NPin.Framework.Mapster; -using NPin.Framework.SqlSugarCore; -using NPin.Framework.TenantManagement.SqlSugarCore; -using NPin.Framework.Upms.SqlSugarCore; - -namespace NPin.SqlSugarCore; - -[DependsOn( - typeof(NPinDomainModule), - typeof(NPinFrameworkUpmsSqlSugarCoreModule), - // TODO bbs - // TODO codegen - typeof(NPinFrameworkAuditLoggingSqlSugarCoreModule), - typeof(NPinFrameworkTenantManagementSqlSugarCoreModule), - // - typeof(NPinFrameworkMapsterModule), - typeof(NPinFrameworkSqlSugarCoreModule) -)] -public class NPinSqlSugarCoreModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddNPinDbContext(); - // 默认不开放,可根据项目需要是否直接对外开放db - // context.Services.AddTransient(x => x.GetRequiredService().SqlSugarClient); - } +using NPin.Domain; +using NPin.Framework.AuditLogging.SqlSugarCore; +using NPin.Framework.Mapster; +using NPin.Framework.SqlSugarCore; +using NPin.Framework.TenantManagement.SqlSugarCore; +using NPin.Framework.Upms.SqlSugarCore.Repositories; + +namespace NPin.SqlSugarCore; + +[DependsOn( + typeof(NPinDomainModule), + typeof(NPinFrameworkUpmsSqlSugarCoreModule), + // TODO bbs + // TODO codegen + typeof(NPinFrameworkAuditLoggingSqlSugarCoreModule), + typeof(NPinFrameworkTenantManagementSqlSugarCoreModule), + // + typeof(NPinFrameworkMapsterModule), + typeof(NPinFrameworkSqlSugarCoreModule) +)] +public class NPinSqlSugarCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddNPinDbContext(); + // 默认不开放,可根据项目需要是否直接对外开放db + // context.Services.AddTransient(x => x.GetRequiredService().SqlSugarClient); + } } \ No newline at end of file diff --git a/src/NPin.Web/NPinWebModule.cs b/src/NPin.Web/NPinWebModule.cs index 6548d35..beae995 100644 --- a/src/NPin.Web/NPinWebModule.cs +++ b/src/NPin.Web/NPinWebModule.cs @@ -30,7 +30,7 @@ using Volo.Abp.Caching; using Volo.Abp.MultiTenancy; using Volo.Abp.Swashbuckle; -namespace NPin; +namespace NPin.Web; [DependsOn( typeof(NPinSqlSugarCoreModule), diff --git a/src/NPin.Web/Program.cs b/src/NPin.Web/Program.cs index de118f8..8eb4e83 100644 --- a/src/NPin.Web/Program.cs +++ b/src/NPin.Web/Program.cs @@ -1,5 +1,5 @@ -using NPin; +using NPin.Web; using Serilog; using Serilog.Events; diff --git a/src/NPin.Web/Properties/launchSettings.json b/src/NPin.Web/Properties/launchSettings.json index 4d145a1..29e3d78 100644 --- a/src/NPin.Web/Properties/launchSettings.json +++ b/src/NPin.Web/Properties/launchSettings.json @@ -1,15 +1,24 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "NPin.Web": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "dotnetRunMessages": true, - "applicationUrl": "http://localhost:19001" - } - } -} +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "NPin.Web": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:19000" + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": false, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": { + "ASPNETCORE_HTTP_PORTS": "19000" + }, + "publishAllPorts": true + } + } +} diff --git a/src/NPin.Web/appsettings.json b/src/NPin.Web/appsettings.json index 39b87e5..9facca9 100644 --- a/src/NPin.Web/appsettings.json +++ b/src/NPin.Web/appsettings.json @@ -8,8 +8,8 @@ }, // 应用启动 "App": { - "SelfUrl": "http://*:19001", - "CorsOrigins": "http://localhost:19001;http://localhost:18000" + "SelfUrl": "http://*:19000", + "CorsOrigins": "http://localhost:19000;http://localhost:18000" }, // 数据库类型列表 "DbList": [