Browse Source

Merge pull request #1149 from feijie999/dev

更新AIO模板项目,加入User实体的demo数据和基于数据库的单元测试示例
pull/1162/head
yx lin 11 months ago
committed by GitHub
parent
commit
6483fc82f1
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 403
      aspnet-core/templates/aio/content/Directory.Packages.props
  2. 170
      aspnet-core/templates/aio/content/README.md
  3. 170
      aspnet-core/templates/aio/content/README.zh-CN.md
  4. 11
      aspnet-core/templates/aio/content/common.props
  5. 72
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs
  6. 91
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs
  7. 494
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj
  8. 1
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs
  9. 16
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json
  10. 18
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json
  11. 73
      aspnet-core/templates/aio/content/migrations/Migrate.ps1
  12. 2
      aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule.cs
  13. 15
      aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/IProjectNameDataSeeder.cs
  14. 226
      aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ProjectNameDataSeeder.cs
  15. 6
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs
  16. 8
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs
  17. 37
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/CreateUpdateUserDto.cs
  18. 39
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/UserDto.cs
  19. 39
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/UserItemDto.cs
  20. 14
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/UserPagedAndSortedResultRequestDto.cs
  21. 55
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/IUserAppService.cs
  22. 1
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj
  23. 10
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs
  24. 2
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs
  25. 211
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/Users/UserAppService.cs
  26. 4
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj
  27. 4
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs
  28. 21
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/TreeCodes/IHaveTreeCode.cs
  29. 33
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/TreeCodes/ITreeCodeGenerator.cs
  30. 114
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/TreeCodes/TreeCodeGenerator.cs
  31. 69
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/IUserManager.cs
  32. 9
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/IUserRepository.cs
  33. 59
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/User.cs
  34. 449
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/UserManager.cs
  35. 1
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj
  36. 5
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs
  37. 13
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs
  38. 17
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs
  39. 6
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs
  40. 22
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/Users/UserRepository.cs
  41. 134
      aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/Users/UserController.cs
  42. 5
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj
  43. 137
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/DataSeeder/ProjectNameDataSeederTests.cs
  44. 56
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs
  45. 64
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/TestFileProvider.cs
  46. 21
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/TestHostEnvironment.cs
  47. 265
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/Users/UserAppServiceTests.cs
  48. 6
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj
  49. 62
      aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs

403
aspnet-core/templates/aio/content/Directory.Packages.props

@ -7,51 +7,11 @@
<MicrosoftExtensionsPackageVersion>8.0.0</MicrosoftExtensionsPackageVersion>
<MicrosoftAspNetCorePackageVersion>8.0.0</MicrosoftAspNetCorePackageVersion>
<MicrosoftEntityFrameworkCorePackageVersion>8.0.0</MicrosoftEntityFrameworkCorePackageVersion>
<SerilogPackageVersion>3.1.1</SerilogPackageVersion>
<SerilogAspNetCorePackageVersion>8.0.0</SerilogAspNetCorePackageVersion>
<XunitPackageVersion>2.6.1</XunitPackageVersion>
<OpenTelemetryPackageVersion>1.8.1</OpenTelemetryPackageVersion>
<FodyPackageVersion>6.8.0</FodyPackageVersion>
<MicrosoftTestSdkPackageVersion>17.8.0</MicrosoftTestSdkPackageVersion>
<DaprPackageVersion>1.12.0</DaprPackageVersion>
<IdentityModelPackageVersion>6.2.0</IdentityModelPackageVersion>
<PollyPackageVersion>8.2.0</PollyPackageVersion>
<QuartzPackageVersion>3.7.0</QuartzPackageVersion>
<HangfirePackageVersion>1.8.6</HangfirePackageVersion>
<DistributedLockPackageVersion>1.0.5</DistributedLockPackageVersion>
<DistributedLockRedisPackageVersion>1.0.2</DistributedLockRedisPackageVersion>
<SenparcWeixinPackageVersion>16.18.9</SenparcWeixinPackageVersion>
<ImageSharpPackageVersion>3.0.2</ImageSharpPackageVersion>
<CoverletPackageVersion>6.0.0</CoverletPackageVersion>
<MoqPackageVersion>3.0.0</MoqPackageVersion>
<NSubstitutePackageVersion>5.1.0</NSubstitutePackageVersion>
<ShouldlyPackageVersion>4.2.1</ShouldlyPackageVersion>
<XunitRunnerPackageVersion>2.5.3</XunitRunnerPackageVersion>
<AliyunSdkPackageVersion>1.5.10</AliyunSdkPackageVersion>
<AliyunOssPackageVersion>2.13.0</AliyunOssPackageVersion>
<AgileConfigPackageVersion>1.6.9</AgileConfigPackageVersion>
<MarkdigPackageVersion>0.34.0</MarkdigPackageVersion>
<NewtonsoftJsonPackageVersion>13.0.3</NewtonsoftJsonPackageVersion>
<NestPackageVersion>7.15.1</NestPackageVersion>
<NRulesPackageVersion>0.9.2</NRulesPackageVersion>
<OcelotPackageVersion>20.0.0</OcelotPackageVersion>
<RulesEnginePackageVersion>4.0.0</RulesEnginePackageVersion>
<JetBrainsAnnotationsPackageVersion>2023.3.0</JetBrainsAnnotationsPackageVersion>
<ImageSharpDrawingPackageVersion>2.0.1</ImageSharpDrawingPackageVersion>
<StackExchangeRedisPackageVersion>2.7.4</StackExchangeRedisPackageVersion>
<SwashbucklePackageVersion>6.5.0</SwashbucklePackageVersion>
<HangfireMySqlPackageVersion>2.0.3</HangfireMySqlPackageVersion>
<OpenTelemetryEfCorePackageVersion>1.0.0-beta.11</OpenTelemetryEfCorePackageVersion>
<SystemComponentModelPackageVersion>5.0.0</SystemComponentModelPackageVersion>
<TencentCloudCosPackageVersion>5.4.37</TencentCloudCosPackageVersion>
<TencentCloudSdkPackageVersion>3.0.712</TencentCloudSdkPackageVersion>
<YarpReverseProxyPackageVersion>2.1.0</YarpReverseProxyPackageVersion>
<OpenIddictDataProtectionPackageVersion>5.5.0</OpenIddictDataProtectionPackageVersion>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!-- LINGYUN Abp Framework -->
<ItemGroup>
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.HttpOverrides" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Localization" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
@ -106,8 +66,11 @@
<PackageVersion Include="LINGYUN.Abp.Webhooks.Core" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.EventBus" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Linq.Dynamic.Queryable" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Exporter.MagicodesIE.Excel" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundWorkers.Hangfire" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Hangfire.Dashboard" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="Moq" Version="4.20.70" />
</ItemGroup>
<!-- Abp Framework -->
<ItemGroup>
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="3.2.0" />
@ -176,6 +139,8 @@
<PackageVersion Include="Volo.Abp.Guids" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.GlobalFeatures" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.HangFire" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BackgroundJobs.HangFire" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BackgroundWorkers.Hangfire" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Http.Client.IdentityModel.Web" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.AspNetCore" Version="$(VoloAbpPackageVersion)" />
@ -236,10 +201,9 @@
<PackageVersion Include="Volo.Abp.Users.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Validation" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<!-- .NET -->
<ItemGroup>
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Protocols.Json" Version="$(MicrosoftAspNetCorePackageVersion)" />
@ -255,10 +219,9 @@
<PackageVersion Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftTestSdkPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageVersion Include="System.Text.Json" Version="8.0.0" />
</ItemGroup>
<!-- Elsa -->
<ItemGroup>
<PackageVersion Include="Elsa" Version="$(ElsaPackageVersion)" />
@ -276,7 +239,6 @@
<PackageVersion Include="Elsa.Webhooks.Persistence.EntityFramework.MySql" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.WorkflowSettings.Persistence.EntityFramework.MySql" Version="$(ElsaPackageVersion)" />
</ItemGroup>
<!-- DotNetCore.CAP -->
<ItemGroup>
<PackageVersion Include="DotNetCore.CAP" Version="$(DotNetCoreCAPPackageVersion)" />
@ -289,70 +251,68 @@
<PackageVersion Include="DotNetCore.CAP.SqlServer" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.Sqlite" Version="$(DotNetCoreCAPPackageVersion)" />
</ItemGroup>
<!-- Serilog -->
<ItemGroup>
<PackageVersion Include="Serilog" Version="$(SerilogPackageVersion)" />
<PackageVersion Include="Serilog.AspNetCore" Version="$(SerilogAspNetCorePackageVersion)" />
<PackageVersion Include="Serilog" Version="3.1.1" />
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.0" />
<PackageVersion Include="Serilog.Enrichers.Environment" Version="2.3.0" />
<PackageVersion Include="Serilog.Enrichers.Assembly" Version="2.0.0" />
<PackageVersion Include="Serilog.Enrichers.Process" Version="2.0.2" />
<PackageVersion Include="Serilog.Enrichers.Thread" Version="3.1.0" />
<PackageVersion Include="Serilog.Extensions.Hosting" Version="$(SerilogAspNetCorePackageVersion)" />
<PackageVersion Include="Serilog.Extensions.Logging" Version="$(SerilogAspNetCorePackageVersion)" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="$(SerilogAspNetCorePackageVersion)" />
<PackageVersion Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="8.0.0" />
<PackageVersion Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="5.0.0" />
<PackageVersion Include="Serilog.Sinks.Elasticsearch" Version="9.0.3" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
<!-- Test -->
<ItemGroup>
<PackageVersion Include="coverlet.collector" Version="$(CoverletPackageVersion)" />
<PackageVersion Include="xunit" Version="$(XunitPackageVersion)" />
<PackageVersion Include="xunit.extensibility.execution" Version="$(XunitPackageVersion)" />
<PackageVersion Include="xunit.runner.visualstudio" Version="$(XunitRunnerPackageVersion)" />
<PackageVersion Include="Moq.AutoMock" Version="$(MoqPackageVersion)" />
<PackageVersion Include="NSubstitute" Version="$(NSubstitutePackageVersion)" />
<PackageVersion Include="Shouldly" Version="$(ShouldlyPackageVersion)" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Moq.AutoMock" Version="3.0.0" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="xunit" Version="2.6.1" />
<PackageVersion Include="xunit.extensibility.execution" Version="2.6.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<!-- Fody -->
<ItemGroup>
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" />
<PackageVersion Include="Fody" Version="$(FodyPackageVersion)" />
<PackageVersion Include="Fody" Version="6.8.0" />
</ItemGroup>
<!-- Other -->
<ItemGroup>
<PackageVersion Include="aliyun-net-sdk-core" Version="$(AliyunSdkPackageVersion)" />
<PackageVersion Include="Aliyun.OSS.SDK.NetCore" Version="$(AliyunOssPackageVersion)" />
<PackageVersion Include="AgileConfig.Client" Version="$(AgileConfigPackageVersion)" />
<PackageVersion Include="Dapr.Client" Version="$(DaprPackageVersion)" />
<PackageVersion Include="Dapr.Actors" Version="$(DaprPackageVersion)" />
<PackageVersion Include="Dapr.Actors.AspNetCore" Version="$(DaprPackageVersion)" />
<PackageVersion Include="DistributedLock.Core" Version="$(DistributedLockPackageVersion)" />
<PackageVersion Include="DistributedLock.Redis" Version="$(DistributedLockRedisPackageVersion)" />
<PackageVersion Include="Hangfire.MySqlStorage" Version="$(HangfireMySqlPackageVersion)" />
<PackageVersion Include="HangFire.SqlServer" Version="$(HangfirePackageVersion)" />
<PackageVersion Include="IdentityModel" Version="$(IdentityModelPackageVersion)" />
<PackageVersion Include="JetBrains.Annotations" Version="$(JetBrainsAnnotationsPackageVersion)" />
<PackageVersion Include="Markdig" Version="$(MarkdigPackageVersion)" />
<PackageVersion Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
<PackageVersion Include="NEST" Version="$(NestPackageVersion)" />
<PackageVersion Include="NRules" Version="$(NRulesPackageVersion)" />
<PackageVersion Include="Ocelot.Provider.Polly" Version="$(OcelotPackageVersion)" />
<PackageVersion Include="aliyun-net-sdk-core" Version="1.5.10" />
<PackageVersion Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageVersion Include="AgileConfig.Client" Version="1.6.9" />
<PackageVersion Include="Dapr.Client" Version="1.12.0" />
<PackageVersion Include="Dapr.Actors" Version="1.12.0" />
<PackageVersion Include="Dapr.Actors.AspNetCore" Version="1.12.0" />
<PackageVersion Include="DistributedLock.Core" Version="1.0.5" />
<PackageVersion Include="DistributedLock.Redis" Version="1.0.2" />
<PackageVersion Include="Hangfire.MySqlStorage" Version="2.0.3" />
<PackageVersion Include="HangFire.SqlServer" Version="1.8.6" />
<PackageVersion Include="IdentityModel" Version="6.2.0" />
<PackageVersion Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageVersion Include="Markdig" Version="0.34.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NEST" Version="7.15.1" />
<PackageVersion Include="NRules" Version="0.9.2" />
<PackageVersion Include="Ocelot.Provider.Polly" Version="20.0.0" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="8.0.2" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AuditLogging.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Authentication.QQ" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Authentication.WeChat" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Aliyun.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Aliyun" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent.QQ" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Aliyun.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Aliyun" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent.QQ" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis.Client" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation" Version="$(LINGYUNAbpPackageVersion)" />
@ -362,8 +322,8 @@
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.Client" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Localization.Persistence" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Logging.Serilog.Elasticsearch" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Logging" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Sms.Aliyun" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Logging" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Sms.Aliyun" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenApi.Authorization" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenApi" Version="$(LINGYUNAbpPackageVersion)" />
@ -372,14 +332,14 @@
<PackageVersion Include="LINGYUN.Abp.WeChat.MiniProgram" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Handlers" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Handlers" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Handlers" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
@ -403,135 +363,134 @@
<PackageVersion Include="LINGYUN.Abp.Elsa" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.AspNetCore.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Application" Version="8.3.0" />
<PackageVersion Include="LINGYUN.Abp.Identity.AspNetCore.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.OrganizaztionUnits" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.LinkUser" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Portal" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.SmsValidator" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IM.SignalR" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IM" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Common" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Emailing" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.LinkUser" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Sms" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Portal" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.FileSystem" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Settings.VueVbenAdmin" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Theme.VueVbenAdmin" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Activities" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.EventBus" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Quartz" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Identity" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Saas" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="$(SystemComponentModelPackageVersion)" />
<PackageVersion Include="Tencent.QCloud.Cos.Sdk" Version="$(TencentCloudCosPackageVersion)" />
<PackageVersion Include="TencentCloudSDK" Version="$(TencentCloudSdkPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Exporter.Zipkin" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="$(OpenTelemetryEfCorePackageVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="$(OpenTelemetryPackageVersion)" />
<PackageVersion Include="Polly" Version="$(PollyPackageVersion)" />
<PackageVersion Include="Quartz.Serialization.Json" Version="$(QuartzPackageVersion)" />
<PackageVersion Include="RulesEngine" Version="$(RulesEnginePackageVersion)" />
<PackageVersion Include="Senparc.Weixin.MP" Version="$(SenparcWeixinPackageVersion)" />
<PackageVersion Include="SixLabors.ImageSharp" Version="$(ImageSharpPackageVersion)" />
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="$(ImageSharpDrawingPackageVersion)" />
<PackageVersion Include="StackExchange.Redis" Version="$(StackExchangeRedisPackageVersion)" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="$(SwashbucklePackageVersion)" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="$(SystemComponentModelPackageVersion)" />
<PackageVersion Include="Tencent.QCloud.Cos.Sdk" Version="$(TencentCloudCosPackageVersion)" />
<PackageVersion Include="TencentCloudSDK" Version="$(TencentCloudSdkPackageVersion)" />
<PackageVersion Include="Yarp.ReverseProxy" Version="$(YarpReverseProxyPackageVersion)" />
<PackageVersion Include="OpenIddict.Server.DataProtection" Version="$(OpenIddictDataProtectionPackageVersion)" />
<PackageVersion Include="OpenIddict.Validation.DataProtection" Version="$(OpenIddictDataProtectionPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.OrganizaztionUnits" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.LinkUser" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Portal" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.SmsValidator" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IM.SignalR" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IM" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Common" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Emailing" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.LinkUser" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Sms" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Portal" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat.Work" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.FileSystem" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.SettingManagement" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Settings.VueVbenAdmin" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Theme.VueVbenAdmin" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Activities" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.EventBus" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Quartz" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Identity" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Saas" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Exporter.Zipkin" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.11" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.8.1" />
<PackageVersion Include="Polly" Version="8.2.0" />
<PackageVersion Include="Quartz.Serialization.Json" Version="3.7.0" />
<PackageVersion Include="RulesEngine" Version="4.0.0" />
<PackageVersion Include="Senparc.Weixin.MP" Version="16.18.9" />
<PackageVersion Include="SixLabors.ImageSharp" Version="3.0.2" />
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="2.0.1" />
<PackageVersion Include="StackExchange.Redis" Version="2.7.4" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="Tencent.QCloud.Cos.Sdk" Version="5.4.37" />
<PackageVersion Include="TencentCloudSDK" Version="3.0.712" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.1.0" />
<PackageVersion Include="OpenIddict.Server.DataProtection" Version="5.5.0" />
<PackageVersion Include="OpenIddict.Validation.DataProtection" Version="5.5.0" />
<PackageVersion Include="Hangfire.PostgreSql" Version="1.20.10" />
<PackageVersion Include="Hangfire.Redis.StackExchange" Version="1.9.4" />
</ItemGroup>
</Project>

170
aspnet-core/templates/aio/content/README.md

@ -1,135 +1,133 @@
# LINGYUN.Abp.Templates
# PackageName.CompanyName.ProjectName
[English](README.md) | [中文](README.zh-CN.md)
## Introduction
## Quick Start Guide
LINGYUN.Abp.Templates provides two types of project templates based on ABP Framework:
This guide will help you quickly set up and run the project. Follow these steps to get started.
1. **Microservice Template**: A complete microservice architecture template with distributed services.
2. **All-in-One Template**: A single-application template that combines all services into one project.
### Prerequisites
## Features
- .NET SDK 9.0 or higher
- A supported database (SQL Server, MySQL, PostgreSQL, Oracle, or SQLite)
- PowerShell 7.0+ (recommended for running migration scripts)
### Common Features
### Step 1: Restore and Build the Project
- Integrated authentication (IdentityServer4/OpenIddict)
- Database integration (multiple databases supported)
- Unified configuration management
- Distributed event bus support
- Background job processing
### Microservice Template Features
```bash
# Navigate to the project root directory
cd /path/to/project
- Complete microservice project structure
- Service discovery and registration
- Distributed deployment support
# Restore dependencies
dotnet restore
### All-in-One Template Features
# Build the solution
dotnet build
```
- Simplified deployment
- Easier maintenance
- Lower resource requirements
### Step 2: Create Database Schema
## How to Use
Use the Migrate.ps1 script to create the database tables structure:
### Install labp CLI Tool
```powershell
# Navigate to the migrations directory
cd migrations
```bash
dotnet tool install --global LINGYUN.Abp.Cli
# Run the migration script
./Migrate.ps1
```
### Install Templates
The script will:
1. Detect available DbContext classes in the project
2. Ask you to select which DbContext to use for migration
3. Prompt for a migration name
4. Create the migration
5. Optionally generate SQL scripts for the migration
### Step 3: Initialize Seed Data
Run the DbMigrator project to initialize seed data:
```bash
# Install Microservice Template
dotnet new install LINGYUN.Abp.MicroService.Templates
# Navigate to the DbMigrator project directory
cd migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator
# Install All-in-One Template
dotnet new install LINGYUN.Abp.AllInOne.Templates
# Run the DbMigrator project
dotnet run
```
### Create New Project
The DbMigrator will:
#### For Microservice Project
1. Apply all database migrations
2. Seed initial data (users, roles, etc.)
3. Set up tenant configurations if applicable
```bash
# Short name: lam (LINGYUN Abp Microservice)
labp create YourCompanyName.YourProjectName -pk YourPackageName -t lam -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port
```
### Step 4: Launch the Application
#### For All-in-One Project
After successfully setting up the database, you can run the host project:
```bash
# Short name: laa (LINGYUN Abp AllInOne)
labp create YourCompanyName.YourProjectName -pk YourPackageName -t laa -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port
# Navigate to the host project directory
cd host/PackageName.CompanyName.ProjectName.AIO.Host
# Run the host project
dotnet run --launch-profile "PackageName.CompanyName.ProjectName.Development"
```
## How to Run
The application will start and be accessible at the configured URL (typically [https://localhost:44300](https://localhost:44300)).
After creating your project, you can run it using the following command:
## Database-based Unit Testing
### For Microservice Project
To run database-based unit tests, follow these steps:
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.HttpApi.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
### Step 1: Prepare Test Database
### For All-in-One Project
Before running tests, make sure the test database exists. The test database connection string is defined in the `ProjectNameEntityFrameworkCoreTestModule.cs` file.
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.AIO.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
The default connection string is:
## How to Package and Publish
```csharp
private const string DefaultPostgresConnectionString =
"Host=127.0.0.1;Port=5432;Database=test_db;User Id=postgres;Password=postgres;";
```
1. Clone the Project
You can either create this database manually or modify the connection string to use an existing database.
```bash
git clone <repository-url>
cd <repository-path>/aspnet-core/templates/content
```
### Step 2: Configure Test Environment
2. Modify Version
Edit the project files to update versions:
- For Microservice: `../PackageName.CompanyName.ProjectName.csproj`
- For All-in-One: `../PackageName.CompanyName.ProjectName.AIO.csproj`
Modify the connection string in `ProjectNameEntityFrameworkCoreTestModule.cs` if needed:
```xml
<Version>8.3.0</Version>
```csharp
// You can also set an environment variable to override the default connection string
var connectionString = Environment.GetEnvironmentVariable("TEST_CONNECTION_STRING") ??
DefaultPostgresConnectionString;
```
3. Execute Packaging Script
### Step 3: Run Tests
```powershell
# Windows PowerShell
.\pack.ps1
Run the Application.Tests project:
```bash
# Navigate to the test project directory
cd tests/PackageName.CompanyName.ProjectName.Application.Tests
# PowerShell Core (Windows/Linux/macOS)
pwsh pack.ps1
# Run the tests
dotnet test
```
The script will prompt you to choose which template to package:
The test framework will:
1. Microservice Template
2. All-in-One Template
3. Both Templates
1. Create a clean test database environment
2. Run all unit tests
3. Report test results
## Supported Databases
## Note About Naming
- SqlServer
- MySQL
- PostgreSQL
- Oracle
- SQLite
This is a template project, so all project names contain placeholders that will be replaced when the template is used to create a new project:
## Notes
- `PackageName` will be replaced with your package name
- `CompanyName` will be replaced with your company name
- `ProjectName` will be replaced with your project name
- Ensure .NET SDK 8.0 or higher is installed
- Choose the appropriate template based on your needs:
- Microservice Template: For large-scale distributed applications
- All-in-One Template: For smaller applications or simpler deployment requirements
- Pay attention to NuGet publish address and key when packaging
- Complete testing is recommended before publishing
When creating a new project from this template, you'll specify these values and they'll be substituted throughout the entire solution.

170
aspnet-core/templates/aio/content/README.zh-CN.md

@ -1,135 +1,133 @@
# LINGYUN.Abp.Templates
# PackageName.CompanyName.ProjectName
[English](README.md) | [中文](README.zh-CN.md)
## 简介
## 快速启动指南
LINGYUN.Abp.Templates 基于 ABP Framework 提供两种项目模板:
本指南将帮助您快速设置和运行项目。请按照以下步骤开始。
1. **微服务模板**:完整的分布式微服务架构模板
2. **单体应用模板**:将所有服务集成到一个项目中的单体应用模板
### 前提条件
## 特性
- .NET SDK 9.0 或更高版本
- 支持的数据库(SQL Server、MySQL、PostgreSQL、Oracle 或 SQLite)
- PowerShell 7.0+(推荐用于运行迁移脚本)
### 共同特性
### 第一步:还原和构建项目
- 集成身份认证(支持 IdentityServer4/OpenIddict)
- 数据库集成(支持多种数据库)
- 统一配置管理
- 分布式事件总线支持
- 后台作业处理
```bash
# 导航到项目根目录
cd /path/to/project
### 微服务模板特性
# 还原依赖项
dotnet restore
- 完整的微服务项目结构
- 服务发现与注册
- 支持分布式部署
# 构建解决方案
dotnet build
```
### 单体应用模板特性
### 第二步:创建数据库结构
- 简化的部署流程
- 更容易的维护
- 更低的资源需求
使用 Migrate.ps1 脚本创建数据库表结构:
## 使用方法
```powershell
# 导航到 migrations 目录
cd migrations
### 安装模板
# 运行迁移脚本
./Migrate.ps1
```
```bash
# 安装微服务模板:lam
dotnet new install LINGYUN.Abp.MicroService.Templates
该脚本将:
# 安装单体应用模板:laa
dotnet new install LINGYUN.Abp.AllInOne.Templates
```
1. 检测项目中可用的 DbContext 类
2. 要求您选择用于迁移的 DbContext
3. 提示输入迁移名称
4. 创建迁移
5. 可选地为迁移生成 SQL 脚本
### 安装 labp 命令行工具
### 第三步:初始化种子数据
运行 DbMigrator 项目来初始化种子数据:
```bash
dotnet tool install --global LINGYUN.Abp.Cli
# 导航到 DbMigrator 项目目录
cd migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator
# 运行 DbMigrator 项目
dotnet run
```
### 创建新项目
DbMigrator 将:
#### 创建微服务项目
1. 应用所有数据库迁移
2. 初始化种子数据(用户、角色等)
3. 如适用,设置租户配置
```bash
# 简写名称:lam (LINGYUN Abp Microservice)
labp create YourCompanyName.YourProjectName -pk YourPackageName -t lam -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port
```
### 第四步:启动应用程序
#### 创建单体应用项目
成功设置数据库后,您可以运行 host 项目:
```bash
# 简写名称:laa (LINGYUN Abp AllInOne)
labp create YourCompanyName.YourProjectName -pk YourPackageName -t laa -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port
# 导航到 host 项目目录
cd host/PackageName.CompanyName.ProjectName.AIO.Host
# 运行 host 项目
dotnet run --launch-profile "PackageName.CompanyName.ProjectName.Development"
```
## 运行项目
应用程序将启动并可通过配置的 URL 访问(通常是 [https://localhost:44300](https://localhost:44300))。
创建项目后,可以使用以下命令运行:
## 基于数据库的单元测试
### 运行微服务项目
要运行基于数据库的单元测试,请按照以下步骤操作:
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.HttpApi.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
### 第一步:准备测试数据库
### 运行单体应用项目
在运行测试之前,确保测试数据库存在。测试数据库连接字符串在 `ProjectNameEntityFrameworkCoreTestModule.cs` 文件中定义。
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.AIO.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
默认连接字符串是:
## 打包与发布
```csharp
private const string DefaultPostgresConnectionString =
"Host=127.0.0.1;Port=5432;Database=test_db;User Id=postgres;Password=postgres;";
```
1. 克隆项目
您可以手动创建此数据库或修改连接字符串以使用现有数据库。
```bash
git clone <repository-url>
cd <repository-path>/aspnet-core/templates/content
```
### 第二步:配置测试环境
2. 修改版本号
编辑项目文件更新版本号:
- 微服务模板:`../PackageName.CompanyName.ProjectName.csproj`
- 单体应用模板:`../PackageName.CompanyName.ProjectName.AIO.csproj`
如需修改 `ProjectNameEntityFrameworkCoreTestModule.cs` 中的连接字符串:
```xml
<Version>8.3.0</Version>
```csharp
// 您也可以设置环境变量来覆盖默认连接字符串
var connectionString = Environment.GetEnvironmentVariable("TEST_CONNECTION_STRING") ??
DefaultPostgresConnectionString;
```
3. 执行打包脚本
### 第三步:运行测试
```powershell
# Windows PowerShell
.\pack.ps1
运行 Application.Tests 项目:
```bash
# 导航到测试项目目录
cd tests/PackageName.CompanyName.ProjectName.Application.Tests
# PowerShell Core (Windows/Linux/macOS)
pwsh pack.ps1
# 运行测试
dotnet test
```
脚本会提示您选择要打包的模板
测试框架将
1. 微服务模板
2. 单体应用模板
3. 两种模板都打包
1. 创建清洁的测试数据库环境
2. 运行所有单元测试
3. 报告测试结果
## 支持的数据库
## 关于命名的说明
- SqlServer
- MySQL
- PostgreSQL
- Oracle
- SQLite
这是一个模板项目,所以所有项目名称包含的占位符在使用模板创建新项目时将被替换:
## 注意事项
- `PackageName` 将被替换为您的包名
- `CompanyName` 将被替换为您的公司名
- `ProjectName` 将被替换为您的项目名
- 确保已安装 .NET SDK 8.0 或更高版本
- 根据需求选择合适的模板:
- 微服务模板:适用于大规模分布式应用
- 单体应用模板:适用于小型应用或简单部署需求
- 打包时注意 NuGet 发布地址和密钥
- 发布前建议进行完整测试
当从此模板创建新项目时,您将指定这些值,它们将在整个解决方案中进行替换。

11
aspnet-core/templates/aio/content/common.props

@ -3,13 +3,15 @@
<LangVersion>latest</LangVersion>
<Version>8.2.1</Version>
<Authors>colin</Authors>
<NoWarn>$(NoWarn);CS1591;CS0436;CS8618;NU1803</NoWarn>
<NoWarn>$(NoWarn);CS1591;CS0436;CS8618;NU1803;NU1900</NoWarn>
<PackageProjectUrl>https://github.com/colinin/abp-next-admin</PackageProjectUrl>
<PackageOutputPath>$(SolutionDir)LocalNuget</PackageOutputPath>
<PackageVersion>8.2.1</PackageVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/colinin/abp-next-admin</RepositoryUrl>
<!-- 启用XML文档生成 -->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
<GeneratePackageOnBuild Condition="$(AssemblyName.StartsWith('LINGYUN'))">true</GeneratePackageOnBuild>
</PropertyGroup>
@ -30,9 +32,4 @@
<EmbeddedResource Remove="Modules\**" />
<None Remove="Modules\**" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>$(SolutionDir)LocalNuget</OutputPath>
</PropertyGroup>
</Project>

72
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs

@ -1,8 +1,8 @@
using Elsa;
using Elsa.Options;
using Hangfire;
using Hangfire.Redis.StackExchange;
using LINGYUN.Abp.Aliyun.Localization;
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.DataProtectionManagement;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.Exporter.MiniExcel;
@ -29,7 +29,6 @@ using LINGYUN.Abp.WeChat.Work;
using LINGYUN.Abp.Wrapper;
using LINGYUN.Platform.Localization;
using PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection;
using PackageName.CompanyName.ProjectName.EntityFrameworkCore;
using Medallion.Threading;
using Medallion.Threading.Redis;
using Microsoft.AspNetCore.Authentication.Cookies;
@ -41,13 +40,11 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.IdentityModel.Logging;
using Microsoft.OpenApi.Models;
using MiniExcelLibs.Attributes;
using OpenIddict.Server;
using OpenIddict.Server.AspNetCore;
using PackageName.CompanyName.ProjectName.AIO.Host.Authentication;
using PackageName.CompanyName.ProjectName.AIO.Host.IdentityResources;
using PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages;
using Quartz;
using StackExchange.Redis;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
@ -56,9 +53,11 @@ using System.Text.Unicode;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.AspNetCore.Mvc.Libs;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.Auditing;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Caching;
@ -77,13 +76,13 @@ using Volo.Abp.MultiTenancy;
using Volo.Abp.OpenIddict;
using Volo.Abp.OpenIddict.Localization;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Quartz;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement;
using Volo.Abp.SettingManagement.Localization;
using Volo.Abp.Threading;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
using PackageName.CompanyName.ProjectName.EntityFrameworkCore;
using VoloAbpExceptionHandlingOptions = Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingOptions;
namespace PackageName.CompanyName.ProjectName.AIO.Host;
@ -232,34 +231,6 @@ public partial class MicroServiceApplicationsSingleModule
}
}
private void PreConfigureQuartz(IConfiguration configuration)
{
PreConfigure<AbpQuartzOptions>(options =>
{
// 如果使用持久化存储, 则配置quartz持久层
if (configuration.GetSection("Quartz:UsePersistentStore").Get<bool>())
{
var settings = configuration.GetSection("Quartz:Properties").Get<Dictionary<string, string>>();
if (settings != null)
{
foreach (var setting in settings)
{
options.Properties[setting.Key] = setting.Value;
}
}
options.Configurator += (config) =>
{
config.UsePersistentStore(store =>
{
store.UseProperties = false;
store.UseNewtonsoftJsonSerializer();
});
};
}
});
}
private void PreConfigureElsa(IServiceCollection services, IConfiguration configuration)
{
var elsaSection = configuration.GetSection("Elsa");
@ -406,17 +377,6 @@ public partial class MicroServiceApplicationsSingleModule
});
}
private void ConfigureBackgroundTasks()
{
Configure<AbpBackgroundTasksOptions>(options =>
{
options.NodeName = ApplicationName;
options.JobCleanEnabled = true;
options.JobFetchEnabled = true;
options.JobCheckEnabled = true;
});
}
private void ConfigureTextTemplating(IConfiguration configuration)
{
if (configuration.GetValue<bool>("TextTemplating:IsDynamicStoreEnabled"))
@ -767,6 +727,28 @@ public partial class MicroServiceApplicationsSingleModule
// }
//);
});
Configure<AbpMvcLibsOptions>(options =>
{
options.CheckLibs = false;
});
}
private void ConfigureHangfire(IServiceCollection services, IConfiguration configuration)
{
// 配置Hangfire存储和设置
Configure<AbpBackgroundWorkerOptions>(options =>
{
options.IsEnabled = true;
});
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
// 配置Hangfire
services.AddHangfire(config =>
{
config.UseRedisStorage(redis);
});
}
private void ConfigureLocalization()

91
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs

@ -10,22 +10,11 @@ using LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
using LINGYUN.Abp.Authentication.QQ;
using LINGYUN.Abp.Authentication.WeChat;
using LINGYUN.Abp.Authorization.OrganizationUnits;
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.BackgroundTasks.Activities;
using LINGYUN.Abp.BackgroundTasks.DistributedLocking;
using LINGYUN.Abp.BackgroundTasks.EventBus;
using LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
using LINGYUN.Abp.BackgroundTasks.Jobs;
using LINGYUN.Abp.BackgroundTasks.Notifications;
using LINGYUN.Abp.BackgroundTasks.Quartz;
using LINGYUN.Abp.CachingManagement;
using LINGYUN.Abp.CachingManagement.StackExchangeRedis;
using LINGYUN.Abp.Dapr.Client;
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.DataProtectionManagement;
using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore;
// using LINGYUN.Abp.Demo;
// using LINGYUN.Abp.Demo.EntityFrameworkCore;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.Exporter.MiniExcel;
@ -66,7 +55,6 @@ using LINGYUN.Abp.OpenIddict.WeChat;
using LINGYUN.Abp.OpenIddict.WeChat.Work;
using LINGYUN.Abp.OssManagement;
using LINGYUN.Abp.OssManagement.FileSystem;
// using LINGYUN.Abp.OssManagement.Imaging;
using LINGYUN.Abp.OssManagement.SettingManagement;
using LINGYUN.Abp.PermissionManagement;
using LINGYUN.Abp.PermissionManagement.HttpApi;
@ -77,8 +65,6 @@ using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.SettingManagement;
using LINGYUN.Abp.Sms.Aliyun;
using LINGYUN.Abp.TaskManagement;
using LINGYUN.Abp.TaskManagement.EntityFrameworkCore;
using LINGYUN.Abp.Tencent.QQ;
using LINGYUN.Abp.Tencent.SettingManagement;
using LINGYUN.Abp.TextTemplating;
@ -111,8 +97,11 @@ using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs.Hangfire;
using Volo.Abp.BackgroundWorkers.Hangfire;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using Volo.Abp.EventBus;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Imaging;
@ -124,20 +113,9 @@ using Volo.Abp.PermissionManagement.OpenIddict;
using Volo.Abp.SettingManagement;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Threading;
#if MySQL
using Volo.Abp.EntityFrameworkCore.MySQL;
#elif SqlServer
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Microsoft.EntityFrameworkCore.Infrastructure;
#elif Sqlite
using Volo.Abp.EntityFrameworkCore.Sqlite;
#elif Oracle
using Volo.Abp.EntityFrameworkCore.Oracle;
#elif OracleDevart
using Volo.Abp.EntityFrameworkCore.Oracle.Devart;
#elif PostgreSql
using Volo.Abp.EntityFrameworkCore.PostgreSql;
#endif
// using LINGYUN.Abp.Demo;
// using LINGYUN.Abp.Demo.EntityFrameworkCore;
// using LINGYUN.Abp.OssManagement.Imaging;
namespace PackageName.CompanyName.ProjectName.AIO.Host;
@ -172,12 +150,6 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpNotificationsApplicationModule),
typeof(AbpNotificationsHttpApiModule),
typeof(AbpNotificationsEntityFrameworkCoreModule),
//typeof(AbpIdentityServerSessionModule),
//typeof(AbpIdentityServerApplicationModule),
//typeof(AbpIdentityServerHttpApiModule),
//typeof(AbpIdentityServerEntityFrameworkCoreModule),
typeof(AbpOpenIddictAspNetCoreModule),
typeof(AbpOpenIddictAspNetCoreSessionModule),
typeof(AbpOpenIddictApplicationModule),
@ -188,6 +160,9 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpOpenIddictWeChatModule),
typeof(AbpOpenIddictWeChatWorkModule),
typeof(AbpBackgroundWorkersHangfireModule),
typeof(AbpBackgroundJobsHangfireModule),
//typeof(AbpOssManagementMinioModule), // 取消注释以使用Minio
typeof(AbpOssManagementFileSystemModule),
// typeof(AbpOssManagementImagingModule),
@ -210,11 +185,6 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpSaasHttpApiModule),
typeof(AbpSaasEntityFrameworkCoreModule),
typeof(TaskManagementDomainModule),
typeof(TaskManagementApplicationModule),
typeof(TaskManagementHttpApiModule),
typeof(TaskManagementEntityFrameworkCoreModule),
typeof(AbpTextTemplatingDomainModule),
typeof(AbpTextTemplatingApplicationModule),
typeof(AbpTextTemplatingHttpApiModule),
@ -246,19 +216,7 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理
#if MySQL
typeof(AbpEntityFrameworkCoreMySQLModule),
#elif SqlServer
typeof(AbpEntityFrameworkCoreSqlServerModule),
#elif Sqlite
typeof(AbpEntityFrameworkCoreSqliteModule),
#elif Oracle
typeof(AbpEntityFrameworkCoreOracleModule),
#elif OracleDevart
typeof(AbpEntityFrameworkCoreOracleDevartModule),
#elif PostgreSql
typeof(AbpEntityFrameworkCorePostgreSqlModule),
#endif
typeof(AbpAliyunSmsModule),
typeof(AbpAliyunSettingManagementModule),
@ -268,24 +226,9 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpAuthorizationOrganizationUnitsModule),
typeof(AbpIdentityOrganizaztionUnitsModule),
typeof(AbpBackgroundTasksModule),
typeof(AbpBackgroundTasksActivitiesModule),
typeof(AbpBackgroundTasksDistributedLockingModule),
typeof(AbpBackgroundTasksEventBusModule),
typeof(AbpBackgroundTasksExceptionHandlingModule),
typeof(AbpBackgroundTasksJobsModule),
typeof(AbpBackgroundTasksNotificationsModule),
typeof(AbpBackgroundTasksQuartzModule),
typeof(AbpDataProtectionManagementApplicationModule),
typeof(AbpDataProtectionManagementHttpApiModule),
typeof(AbpDataProtectionManagementEntityFrameworkCoreModule),
// typeof(AbpDemoApplicationModule),
// typeof(AbpDemoHttpApiModule),
// typeof(AbpDemoEntityFrameworkCoreModule),
typeof(AbpDaprClientModule),
typeof(AbpExceptionHandlingModule),
typeof(AbpEmailingExceptionHandlingModule),
typeof(AbpFeaturesLimitValidationModule),
@ -327,17 +270,6 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpAccountTemplatesModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpCachingStackExchangeRedisModule),
// typeof(AbpElsaModule),
// typeof(AbpElsaServerModule),
// typeof(AbpElsaActivitiesModule),
// typeof(AbpElsaEntityFrameworkCoreModule),
// typeof(AbpElsaEntityFrameworkCorePostgreSqlModule),
// typeof(AbpElsaModule),
// typeof(AbpElsaServerModule),
// typeof(AbpElsaActivitiesModule),
// typeof(AbpElsaEntityFrameworkCoreModule),
// typeof(AbpElsaEntityFrameworkCoreMySqlModule),
typeof(AbpExporterMiniExcelModule),
typeof(AbpAspNetCoreMvcUiMultiTenancyModule),
typeof(AbpAspNetCoreSerilogModule),
@ -348,7 +280,7 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host;
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpEventBusModule),
typeof(AbpAutofacModule),
typeof(ProjectNameApplicationModule),
typeof(ProjectNameHttpApiModule),
typeof(ProjectNameEntityFrameworkCoreModule),
@ -365,7 +297,6 @@ public partial class MicroServiceApplicationsSingleModule : AbpModule
PreConfigureFeature();
PreConfigureIdentity();
PreConfigureApp(configuration);
PreConfigureQuartz(configuration);
PreConfigureAuthServer(configuration);
PreConfigureElsa(context.Services, configuration);
PreConfigureCertificate(configuration, hostingEnvironment);
@ -386,7 +317,7 @@ public partial class MicroServiceApplicationsSingleModule : AbpModule
ConfigureDataSeeder();
ConfigureLocalization();
ConfigureKestrelServer();
ConfigureBackgroundTasks();
ConfigureHangfire(context.Services, configuration);
ConfigureExceptionHandling();
ConfigureVirtualFileSystem();
ConfigureEntityDataProtected();

494
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj

@ -2,264 +2,260 @@
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<NoWarn>$(NoWarn);CS1591;CS0436;CS8618;NU1803;NU1900</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DistributedLock.Redis" />
<PackageReference Include="Elsa.Activities.Email" />
<PackageReference Include="Elsa.Activities.Http" />
<PackageReference Include="Elsa.Activities.UserTask" />
<PackageReference Include="Elsa.Activities.Temporal.Quartz" />
<PackageReference Include="DistributedLock.Redis"/>
<PackageReference Include="Elsa.Activities.Email"/>
<PackageReference Include="Elsa.Activities.Http"/>
<PackageReference Include="Elsa.Activities.UserTask"/>
<PackageReference Include="Elsa.Activities.Temporal.Quartz"/>
<!--<PackageReference Include="Elsa.Designer.Components.Web" />-->
<PackageReference Include="Elsa.Webhooks.Api" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" />
<PackageReference Include="OpenIddict.Validation.DataProtection" />
<PackageReference Include="OpenIddict.Server.DataProtection" />
<PackageReference Include="Serilog.AspNetCore" />
<PackageReference Include="Serilog.Enrichers.Environment" />
<PackageReference Include="Serilog.Enrichers.Assembly" />
<PackageReference Include="Serilog.Enrichers.Process" />
<PackageReference Include="Serilog.Enrichers.Thread" />
<PackageReference Include="Serilog.Settings.Configuration" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="Swashbuckle.AspNetCore" />
<PackageReference Include="Quartz.Serialization.Json" />
<PackageReference Include="Volo.Abp.Account.Web.OpenIddict" />
<PackageReference Include="Elsa.Webhooks.Api"/>
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis"/>
<PackageReference Include="OpenIddict.Validation.DataProtection"/>
<PackageReference Include="OpenIddict.Server.DataProtection"/>
<PackageReference Include="Serilog.AspNetCore"/>
<PackageReference Include="Serilog.Enrichers.Environment"/>
<PackageReference Include="Serilog.Enrichers.Assembly"/>
<PackageReference Include="Serilog.Enrichers.Process"/>
<PackageReference Include="Serilog.Enrichers.Thread"/>
<PackageReference Include="Serilog.Settings.Configuration"/>
<PackageReference Include="Serilog.Sinks.Elasticsearch"/>
<PackageReference Include="Serilog.Sinks.File"/>
<PackageReference Include="Swashbuckle.AspNetCore"/>
<PackageReference Include="Quartz.Serialization.Json"/>
<PackageReference Include="Volo.Abp.Account.Web.OpenIddict"/>
<!--<PackageReference Include="Volo.Abp.Account.Web.IdentityServer" />-->
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" />
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Volo.Abp.Autofac" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySql" Condition="'$(MySQL)'=='true'" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Condition="'$(SqlServer)'=='true'" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.Sqlite" Condition="'$(Sqlite)'=='true'" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.Oracle" Condition="'$(Oracle)'=='true'" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.Oracle.Devart" Condition="'$(OracleDevart)'=='true'" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Condition="'$(PostgreSql)'=='true'" />
<PackageReference Include="Volo.Abp.FeatureManagement.Application" />
<PackageReference Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.FeatureManagement.HttpApi" />
<PackageReference Include="Volo.Abp.PermissionManagement.Application" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.IdentityServer" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" />
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi" />
<PackageReference Include="Volo.Abp.Identity.AspNetCore" />
<PackageReference Include="Volo.Abp.Imaging.ImageSharp" />
<PackageReference Include="Volo.Abp.AspNetCore.Serilog"/>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy"/>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic"/>
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer"/>
<PackageReference Include="Volo.Abp.Autofac"/>
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis"/>
<PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql"/>
<PackageReference Include="Volo.Abp.FeatureManagement.Application"/>
<PackageReference Include="Volo.Abp.FeatureManagement.EntityFrameworkCore"/>
<PackageReference Include="Volo.Abp.FeatureManagement.HttpApi"/>
<PackageReference Include="Volo.Abp.PermissionManagement.Application"/>
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity"/>
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.IdentityServer"/>
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.OpenIddict"/>
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi"/>
<PackageReference Include="Volo.Abp.Identity.AspNetCore"/>
<PackageReference Include="Volo.Abp.Imaging.ImageSharp"/>
<!--<PackageReference Include="Volo.Abp.IdentityServer.EntityFrameworkCore" />-->
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.OpenIddict.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore"/>
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore"/>
<PackageReference Include="Volo.Abp.OpenIddict.EntityFrameworkCore"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="LINGYUN.Abp.AuditLogging.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.AuditLogging" />
<PackageReference Include="LINGYUN.Abp.Authentication.QQ" />
<PackageReference Include="LINGYUN.Abp.Authentication.WeChat" />
<PackageReference Include="LINGYUN.Abp.Authorization.OrganizationUnits" />
<PackageReference Include="LINGYUN.Abp.Aliyun.SettingManagement" />
<PackageReference Include="LINGYUN.Abp.Aliyun" />
<PackageReference Include="LINGYUN.Abp.Tencent.QQ" />
<PackageReference Include="LINGYUN.Abp.Tencent.SettingManagement" />
<PackageReference Include="LINGYUN.Abp.Tencent" />
<PackageReference Include="LINGYUN.Abp.AspNetCore.HttpOverrides" />
<PackageReference Include="LINGYUN.Abp.Data.DbMigrator" />
<PackageReference Include="LINGYUN.Abp.ExceptionHandling.Emailing" />
<PackageReference Include="LINGYUN.Abp.ExceptionHandling" />
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation.Redis.Client" />
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation.Redis" />
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation" />
<PackageReference Include="LINGYUN.Abp.Http.Client.Wrapper" />
<PackageReference Include="LINGYUN.Abp.IdGenerator" />
<PackageReference Include="LINGYUN.Abp.RealTime" />
<PackageReference Include="LINGYUN.Abp.Wrapper" />
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application" />
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.HttpApi" />
<PackageReference Include="LINGYUN.Linq.Dynamic.Queryable" />
<PackageReference Include="LINGYUN.Abp.Exporter.MiniExcel" />
<PackageReference Include="LINGYUN.Abp.FeatureManagement.Client" />
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Localization" />
<PackageReference Include="LINGYUN.Abp.Localization.CultureMap" />
<PackageReference Include="LINGYUN.Abp.Localization.Persistence" />
<PackageReference Include="LINGYUN.Abp.Logging.Serilog.Elasticsearch" />
<PackageReference Include="LINGYUN.Abp.Logging" />
<PackageReference Include="LINGYUN.Abp.Serilog.Enrichers.Application" />
<PackageReference Include="LINGYUN.Abp.Serilog.Enrichers.UniqueId" />
<PackageReference Include="LINGYUN.Abp.Sms.Aliyun" />
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper" />
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper" />
<PackageReference Include="LINGYUN.Abp.UI.Navigation" />
<PackageReference Include="LINGYUN.Abp.OpenApi.Authorization" />
<PackageReference Include="LINGYUN.Abp.OpenApi" />
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.MultiTenancy.Editions" />
<PackageReference Include="LINGYUN.Abp.Identity.WeChat" />
<PackageReference Include="LINGYUN.Abp.WeChat.MiniProgram" />
<PackageReference Include="LINGYUN.Abp.WeChat.Official.Handlers" />
<PackageReference Include="LINGYUN.Abp.WeChat.Official" />
<PackageReference Include="LINGYUN.Abp.WeChat.Official.Application" />
<PackageReference Include="LINGYUN.Abp.WeChat.Official.HttpApi" />
<PackageReference Include="LINGYUN.Abp.WeChat.SettingManagement" />
<PackageReference Include="LINGYUN.Abp.WeChat.Work.Application" />
<PackageReference Include="LINGYUN.Abp.WeChat.Work.Handlers" />
<PackageReference Include="LINGYUN.Abp.WeChat.Work.HttpApi" />
<PackageReference Include="LINGYUN.Abp.WeChat.Work" />
<PackageReference Include="LINGYUN.Abp.WeChat" />
<PackageReference Include="LINGYUN.Abp.AuditLogging.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.AuditLogging"/>
<PackageReference Include="LINGYUN.Abp.Authentication.QQ"/>
<PackageReference Include="LINGYUN.Abp.Authentication.WeChat"/>
<PackageReference Include="LINGYUN.Abp.Authorization.OrganizationUnits"/>
<PackageReference Include="LINGYUN.Abp.Aliyun.SettingManagement"/>
<PackageReference Include="LINGYUN.Abp.Aliyun"/>
<PackageReference Include="LINGYUN.Abp.Tencent.QQ"/>
<PackageReference Include="LINGYUN.Abp.Tencent.SettingManagement"/>
<PackageReference Include="LINGYUN.Abp.Tencent"/>
<PackageReference Include="LINGYUN.Abp.AspNetCore.HttpOverrides"/>
<PackageReference Include="LINGYUN.Abp.Data.DbMigrator"/>
<PackageReference Include="LINGYUN.Abp.ExceptionHandling.Emailing"/>
<PackageReference Include="LINGYUN.Abp.ExceptionHandling"/>
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation.Redis.Client"/>
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation.Redis"/>
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation"/>
<PackageReference Include="LINGYUN.Abp.Http.Client.Wrapper"/>
<PackageReference Include="LINGYUN.Abp.IdGenerator"/>
<PackageReference Include="LINGYUN.Abp.RealTime"/>
<PackageReference Include="LINGYUN.Abp.Wrapper"/>
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application"/>
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.HttpApi"/>
<PackageReference Include="LINGYUN.Linq.Dynamic.Queryable"/>
<PackageReference Include="LINGYUN.Abp.Exporter.MiniExcel"/>
<PackageReference Include="LINGYUN.Abp.FeatureManagement.Client"/>
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Localization"/>
<PackageReference Include="LINGYUN.Abp.Localization.CultureMap"/>
<PackageReference Include="LINGYUN.Abp.Localization.Persistence"/>
<PackageReference Include="LINGYUN.Abp.Logging.Serilog.Elasticsearch"/>
<PackageReference Include="LINGYUN.Abp.Logging"/>
<PackageReference Include="LINGYUN.Abp.Serilog.Enrichers.Application"/>
<PackageReference Include="LINGYUN.Abp.Serilog.Enrichers.UniqueId"/>
<PackageReference Include="LINGYUN.Abp.Sms.Aliyun"/>
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper"/>
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper"/>
<PackageReference Include="LINGYUN.Abp.UI.Navigation"/>
<PackageReference Include="LINGYUN.Abp.OpenApi.Authorization"/>
<PackageReference Include="LINGYUN.Abp.OpenApi"/>
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.MultiTenancy.Editions"/>
<PackageReference Include="LINGYUN.Abp.Identity.WeChat"/>
<PackageReference Include="LINGYUN.Abp.WeChat.MiniProgram"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Official.Handlers"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Official"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Official.Application"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Official.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.WeChat.SettingManagement"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Work.Application"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Work.Handlers"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Work.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.WeChat.Work"/>
<PackageReference Include="LINGYUN.Abp.WeChat"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="LINGYUN.Abp.Account.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.Account.Application" />
<PackageReference Include="LINGYUN.Abp.Account.HttpApi" />
<PackageReference Include="LINGYUN.Abp.Account.Templates" />
<PackageReference Include="LINGYUN.Abp.Auditing.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.Auditing.Application" />
<PackageReference Include="LINGYUN.Abp.Auditing.HttpApi" />
<PackageReference Include="LINGYUN.Abp.CachingManagement.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.CachingManagement.Application" />
<PackageReference Include="LINGYUN.Abp.CachingManagement.Domain" />
<PackageReference Include="LINGYUN.Abp.CachingManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.CachingManagement.StackExchangeRedis" />
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.Application" />
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.BlobStoring" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Emailing" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.IM" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Notifications" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Sms" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Webhooks" />
<PackageReference Include="LINGYUN.Abp.Elsa.Activities" />
<!-- <PackageReference Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.PostgreSql" />-->
<PackageReference Include="LINGYUN.Abp.Elsa.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.Elsa.Server" />
<PackageReference Include="LINGYUN.Abp.Elsa" />
<PackageReference Include="LINGYUN.Abp.FeatureManagement.Application" />
<PackageReference Include="LINGYUN.Abp.FeatureManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.Session" />
<PackageReference Include="LINGYUN.Abp.Identity.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.Identity.Application" />
<PackageReference Include="LINGYUN.Abp.Identity.AspNetCore.Session" />
<PackageReference Include="LINGYUN.Abp.Identity.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.Identity.Domain" />
<PackageReference Include="LINGYUN.Abp.Identity.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.Identity.HttpApi" />
<PackageReference Include="LINGYUN.Abp.Identity.Notifications" />
<PackageReference Include="LINGYUN.Abp.Identity.OrganizaztionUnits" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.Application" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.Domain" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.HttpApi" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.LinkUser" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.Portal" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.SmsValidator" />
<PackageReference Include="LINGYUN.Abp.IdentityServer.WeChat.Work" />
<PackageReference Include="LINGYUN.Abp.Identity.Session.AspNetCore" />
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Application" />
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Domain" />
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.AspNetCore" />
<PackageReference Include="LINGYUN.Abp.IM.SignalR" />
<PackageReference Include="LINGYUN.Abp.IM" />
<PackageReference Include="LINGYUN.Abp.MessageService.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.MessageService.Application" />
<PackageReference Include="LINGYUN.Abp.MessageService.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.MessageService.Domain" />
<PackageReference Include="LINGYUN.Abp.MessageService.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.MessageService.HttpApi" />
<PackageReference Include="LINGYUN.Abp.ExceptionHandling.Notifications" />
<PackageReference Include="LINGYUN.Abp.Notifications.Common" />
<PackageReference Include="LINGYUN.Abp.Notifications.Core" />
<PackageReference Include="LINGYUN.Abp.Notifications.Emailing" />
<PackageReference Include="LINGYUN.Abp.Notifications.SignalR" />
<PackageReference Include="LINGYUN.Abp.Notifications.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.Notifications.Application" />
<PackageReference Include="LINGYUN.Abp.Notifications.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.Notifications.Domain" />
<PackageReference Include="LINGYUN.Abp.Notifications.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.Notifications.HttpApi" />
<PackageReference Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram" />
<PackageReference Include="LINGYUN.Abp.Notifications.WeChat.Work" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.Application" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.HttpApi" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.LinkUser" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.Sms" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.Portal" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.WeChat" />
<PackageReference Include="LINGYUN.Abp.OpenIddict.WeChat.Work" />
<PackageReference Include="LINGYUN.Abp.OssManagement.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.OssManagement.Application" />
<PackageReference Include="LINGYUN.Abp.OssManagement.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.OssManagement.Domain" />
<PackageReference Include="LINGYUN.Abp.OssManagement.FileSystem" />
<!-- <PackageReference Include="LINGYUN.Abp.OssManagement.Imaging" />-->
<!-- <PackageReference Include="LINGYUN.Abp.OssManagement.Minio" />-->
<PackageReference Include="LINGYUN.Abp.OssManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.OssManagement.SettingManagement" />
<PackageReference Include="LINGYUN.Abp.PermissionManagement.Application" />
<PackageReference Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits" />
<PackageReference Include="LINGYUN.Abp.PermissionManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin" />
<PackageReference Include="LINGYUN.Platform.Application.Contracts" />
<PackageReference Include="LINGYUN.Platform.Application" />
<PackageReference Include="LINGYUN.Platform.Application.Contracts" />
<PackageReference Include="LINGYUN.Platform.Application" />
<PackageReference Include="LINGYUN.Platform.Domain.Shared" />
<PackageReference Include="LINGYUN.Platform.Domain" />
<PackageReference Include="LINGYUN.Platform.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Platform.HttpApi" />
<PackageReference Include="LINGYUN.Platform.Settings.VueVbenAdmin" />
<PackageReference Include="LINGYUN.Platform.Theme.VueVbenAdmin" />
<PackageReference Include="LINGYUN.Abp.Saas.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.Saas.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.Saas.Domain" />
<PackageReference Include="LINGYUN.Abp.Saas.Application" />
<PackageReference Include="LINGYUN.Abp.Saas.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.Saas.HttpApi" />
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application" />
<PackageReference Include="LINGYUN.Abp.SettingManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Abstractions" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Activities" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.EventBus" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Jobs" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Notifications" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Quartz" />
<PackageReference Include="LINGYUN.Abp.BackgroundTasks" />
<PackageReference Include="LINGYUN.Abp.TaskManagement.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.TaskManagement.Application" />
<PackageReference Include="LINGYUN.Abp.TaskManagement.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.TaskManagement.Domain" />
<PackageReference Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.TaskManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.TextTemplating.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.TextTemplating.Application" />
<PackageReference Include="LINGYUN.Abp.TextTemplating.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.TextTemplating.Domain" />
<PackageReference Include="LINGYUN.Abp.TextTemplating.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.TextTemplating.HttpApi" />
<PackageReference Include="LINGYUN.Abp.Webhooks.Core" />
<PackageReference Include="LINGYUN.Abp.Webhooks.EventBus" />
<PackageReference Include="LINGYUN.Abp.Webhooks.Identity" />
<PackageReference Include="LINGYUN.Abp.Webhooks.Saas" />
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts" />
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Application" />
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared" />
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Domain" />
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.HttpApi" />
<PackageReference Include="LINGYUN.Abp.Webhooks" />
<PackageReference Include="LINGYUN.Abp.Account.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.Account.Application"/>
<PackageReference Include="LINGYUN.Abp.Account.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.Account.Templates"/>
<PackageReference Include="LINGYUN.Abp.Auditing.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.Auditing.Application"/>
<PackageReference Include="LINGYUN.Abp.Auditing.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.CachingManagement.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.CachingManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.CachingManagement.Domain"/>
<PackageReference Include="LINGYUN.Abp.CachingManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.CachingManagement.StackExchangeRedis"/>
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.BlobStoring"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Emailing"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.IM"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Notifications"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Sms"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Webhooks"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Activities"/>
<!-- <PackageReference Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.PostgreSql" />-->
<PackageReference Include="LINGYUN.Abp.Elsa.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.Elsa.Server"/>
<PackageReference Include="LINGYUN.Abp.Elsa"/>
<PackageReference Include="LINGYUN.Abp.FeatureManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.FeatureManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.Session"/>
<PackageReference Include="LINGYUN.Abp.Identity.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.Identity.Application"/>
<PackageReference Include="LINGYUN.Abp.Identity.AspNetCore.Session"/>
<PackageReference Include="LINGYUN.Abp.Identity.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.Identity.Domain"/>
<PackageReference Include="LINGYUN.Abp.Identity.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.Identity.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.Identity.Notifications"/>
<PackageReference Include="LINGYUN.Abp.Identity.OrganizaztionUnits"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.Application"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.Domain"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.LinkUser"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.Portal"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.SmsValidator"/>
<PackageReference Include="LINGYUN.Abp.IdentityServer.WeChat.Work"/>
<PackageReference Include="LINGYUN.Abp.Identity.Session.AspNetCore"/>
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Domain"/>
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.AspNetCore"/>
<PackageReference Include="LINGYUN.Abp.IM.SignalR"/>
<PackageReference Include="LINGYUN.Abp.IM"/>
<PackageReference Include="LINGYUN.Abp.MessageService.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.MessageService.Application"/>
<PackageReference Include="LINGYUN.Abp.MessageService.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.MessageService.Domain"/>
<PackageReference Include="LINGYUN.Abp.MessageService.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.MessageService.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.ExceptionHandling.Notifications"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Common"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Core"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Emailing"/>
<PackageReference Include="LINGYUN.Abp.Notifications.SignalR"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Application"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.Notifications.Domain"/>
<PackageReference Include="LINGYUN.Abp.Notifications.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.Notifications.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram"/>
<PackageReference Include="LINGYUN.Abp.Notifications.WeChat.Work"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.Application"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.LinkUser"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.Sms"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.Portal"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.WeChat"/>
<PackageReference Include="LINGYUN.Abp.OpenIddict.WeChat.Work"/>
<PackageReference Include="LINGYUN.Abp.OssManagement.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.OssManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.OssManagement.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.OssManagement.Domain"/>
<PackageReference Include="LINGYUN.Abp.OssManagement.FileSystem"/>
<!-- <PackageReference Include="LINGYUN.Abp.OssManagement.Imaging" />-->
<!-- <PackageReference Include="LINGYUN.Abp.OssManagement.Minio" />-->
<PackageReference Include="LINGYUN.Abp.OssManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.OssManagement.SettingManagement"/>
<PackageReference Include="LINGYUN.Abp.PermissionManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits"/>
<PackageReference Include="LINGYUN.Abp.PermissionManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin"/>
<PackageReference Include="LINGYUN.Platform.Application.Contracts"/>
<PackageReference Include="LINGYUN.Platform.Application"/>
<PackageReference Include="LINGYUN.Platform.Domain.Shared"/>
<PackageReference Include="LINGYUN.Platform.Domain"/>
<PackageReference Include="LINGYUN.Platform.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Platform.HttpApi"/>
<PackageReference Include="LINGYUN.Platform.Settings.VueVbenAdmin"/>
<PackageReference Include="LINGYUN.Platform.Theme.VueVbenAdmin"/>
<PackageReference Include="LINGYUN.Abp.Saas.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.Saas.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.Saas.Domain"/>
<PackageReference Include="LINGYUN.Abp.Saas.Application"/>
<PackageReference Include="LINGYUN.Abp.Saas.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.Saas.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.SettingManagement.HttpApi"/>
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.Abstractions"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.Activities"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.EventBus"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.Jobs"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.Notifications"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks.Quartz"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.BackgroundTasks"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.TaskManagement.Application.Contracts"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.TaskManagement.Application"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.TaskManagement.Domain.Shared"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.TaskManagement.Domain"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore"/>-->
<!-- <PackageReference Include="LINGYUN.Abp.TaskManagement.HttpApi"/>-->
<PackageReference Include="LINGYUN.Abp.TextTemplating.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.TextTemplating.Application"/>
<PackageReference Include="LINGYUN.Abp.TextTemplating.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.TextTemplating.Domain"/>
<PackageReference Include="LINGYUN.Abp.TextTemplating.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.TextTemplating.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.Webhooks.Core"/>
<PackageReference Include="LINGYUN.Abp.Webhooks.EventBus"/>
<PackageReference Include="LINGYUN.Abp.Webhooks.Identity"/>
<PackageReference Include="LINGYUN.Abp.Webhooks.Saas"/>
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts"/>
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Application"/>
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared"/>
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Domain"/>
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore"/>
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.HttpApi"/>
<PackageReference Include="LINGYUN.Abp.Webhooks"/>
<PackageReference Include="Volo.Abp.BackgroundWorkers.Hangfire"/>
<PackageReference Include="Volo.Abp.BackgroundJobs.Hangfire"/>
<PackageReference Include="Hangfire.Redis.StackExchange"/>
</ItemGroup>
<ItemGroup>

1
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs

@ -76,6 +76,7 @@ app.UseSwaggerUI(options =>
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support App API");
});
app.UseAuditing();
app.UseAbpHangfireDashboard();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();

16
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json

@ -92,22 +92,6 @@
"BaseUrl": "http://127.0.0.1:30000"
}
},
"Quartz": {
"UsePersistentStore": false,
"Properties": {
"quartz.jobStore.dataSource": "tkm",
"quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz",
"quartz.dataSource.tkm.connectionStringName": "Default",
"quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz",
"quartz.dataSource.tkm.connectionString": "Default": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456",
"quartz.dataSource.tkm.provider": "DatabaseManagementNameConnector",
// "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz",
// "quartz.dataSource.tkm.connectionString": "Default": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456",
// "quartz.dataSource.tkm.provider": "Npgsql",
"quartz.jobStore.clustered": "true",
"quartz.serializer.type": "json"
}
},
"Redis": {
"IsEnabled": true,
"Configuration": "127.0.0.1,defaultDatabase=15",

18
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json

@ -39,24 +39,6 @@
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "Logs/Debug-.log",
"restrictedToMinimumLevel": "Debug",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "Logs/Info-.log",
"restrictedToMinimumLevel": "Information",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {

73
aspnet-core/templates/aio/content/migrations/Migrate.ps1

@ -9,15 +9,76 @@ $env:FROM_MIGRATION = "true"
# 定义项目路径
$projectPath = Resolve-Path (Join-Path $PSScriptRoot "..")
# 定义可用的DbContext
$dbContexts = @{
"1" = @{
Name = "PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName"
Context = "SingleMigrationsDbContext"
Factory = "SingleMigrationsDbContextFactory"
# 定义函数来动态查找所有可用的DbContext
function Get-AvailableDbContexts {
$migrationsPath = Join-Path $projectPath "migrations"
$dbContexts = @{}
$counter = 1
# 查找所有包含EntityFrameworkCore的目录
$efCoreDirectories = Get-ChildItem -Path $migrationsPath -Directory | Where-Object { $_.Name -like "*EntityFrameworkCore*" }
foreach ($dir in $efCoreDirectories) {
# 优先查找 DbContextFactory 文件
$factoryFiles = Get-ChildItem -Path $dir.FullName -Filter "*DbContextFactory.cs" -Recurse -File
# 如果找到了 Factory 文件
$foundFactory = $false
foreach ($factoryFile in $factoryFiles) {
$factoryContent = Get-Content $factoryFile.FullName -Raw
# 查找 Factory 类名和对应的 DbContext 类
if ($factoryContent -match 'class\s+(\w+Factory)\s*:\s*IDesignTimeDbContextFactory<(\w+)>') {
$factoryName = $matches[1]
$contextName = $matches[2]
# 如果找到了上下文和工厂,添加到列表中
$dbContexts["$counter"] = @{
Name = $dir.Name
Context = $contextName
Factory = $factoryName
}
$counter++
$foundFactory = $true
}
}
# 只有当没有找到 Factory 时,才查找 DbContext 文件作为备选
if (-not $foundFactory) {
$dbContextFiles = Get-ChildItem -Path $dir.FullName -Filter "*DbContext.cs" -Recurse -File
foreach ($contextFile in $dbContextFiles) {
$contextContent = Get-Content $contextFile.FullName -Raw
if ($contextContent -match 'class\s+(\w+DbContext)') {
$contextName = $matches[1]
# 添加到列表中,但没有对应的 Factory
$dbContexts["$counter"] = @{
Name = $dir.Name
Context = $contextName
Factory = $null
}
$counter++
}
}
}
}
# 如果没有找到任何上下文,使用默认的
if ($dbContexts.Count -eq 0) {
$dbContexts["1"] = @{
Name = "PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName"
Context = "SingleMigrationsDbContext"
Factory = "SingleMigrationsDbContextFactory"
}
}
return $dbContexts
}
# 获取可用的DbContext
$dbContexts = Get-AvailableDbContexts
# 显示DbContext选择菜单
function Show-DbContextMenu {
$host.UI.RawUI.BackgroundColor = "Black"

2
aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule.cs

@ -60,7 +60,7 @@ public class SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule : A
options.UseOracle();
options.UseOracle<ProjectNameDbContext>();
#elif PostgreSql
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题
System.AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题
options.UseNpgsql();
options.UseNpgsql<ProjectNameDbContext>();
#endif

15
aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/IProjectNameDataSeeder.cs

@ -0,0 +1,15 @@
using System.Threading.Tasks;
using Volo.Abp.Data;
namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DataSeeder
{
public interface IProjectNameDataSeeder
{
/// <summary>
/// 初始化数据
/// </summary>
/// <param name="context">数据种子上下文</param>
/// <returns>任务</returns>
Task SeedAsync(DataSeedContext context);
}
}

226
aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ProjectNameDataSeeder.cs

@ -0,0 +1,226 @@
using Microsoft.Extensions.Logging;
using PackageName.CompanyName.ProjectName.Users;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
using IdentityRole = Volo.Abp.Identity.IdentityRole;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DataSeeder
{
public class ProjectNameDataSeeder : IProjectNameDataSeeder, ITransientDependency
{
private readonly ICurrentTenant _currentTenant;
private readonly IGuidGenerator _guidGenerator;
private readonly ILogger<ProjectNameDataSeeder> _logger;
private readonly IRepository<User, Guid> _userRepository;
private readonly IdentityUserManager _identityUserManager;
private readonly IdentityRoleManager _identityRoleManager;
private readonly IUnitOfWorkManager _unitOfWorkManager;
/// <summary>
/// 构造函数
/// </summary>
public ProjectNameDataSeeder(
ICurrentTenant currentTenant,
IGuidGenerator guidGenerator,
ILogger<ProjectNameDataSeeder> logger,
IRepository<User, Guid> userRepository,
IdentityUserManager identityUserManager,
IdentityRoleManager identityRoleManager,
IUnitOfWorkManager unitOfWorkManager)
{
_currentTenant = currentTenant;
_guidGenerator = guidGenerator;
_logger = logger;
_userRepository = userRepository;
_identityUserManager = identityUserManager;
_identityRoleManager = identityRoleManager;
_unitOfWorkManager = unitOfWorkManager;
}
/// <summary>
/// 初始化数据
/// </summary>
/// <param name="context">数据种子上下文</param>
/// <returns>任务</returns>
public async Task SeedAsync(DataSeedContext context)
{
using (_currentTenant.Change(context.TenantId))
{
_logger.LogInformation("开始初始化数据...");
// 初始化角色
using (var uow = _unitOfWorkManager.Begin(requiresNew: true))
{
await SeedRolesAsync();
await uow.CompleteAsync();
}
// 初始化用户数据
using (var uow = _unitOfWorkManager.Begin(requiresNew: true))
{
await SeedUsersAsync();
await uow.CompleteAsync();
}
_logger.LogInformation("数据初始化完成");
}
}
/// <summary>
/// 初始化角色数据
/// </summary>
private async Task SeedRolesAsync()
{
// 超级管理员
await CreateRoleIfNotExistsAsync(
"超级管理员",
"系统超级管理员,拥有所有权限");
}
/// <summary>
/// 创建角色(如果不存在)
/// </summary>
private async Task CreateRoleIfNotExistsAsync(string roleName, string description)
{
if (await _identityRoleManager.FindByNameAsync(roleName) == null)
{
var role = new IdentityRole(
_guidGenerator.Create(),
roleName,
_currentTenant.Id)
{
IsStatic = true,
IsPublic = true
};
await _identityRoleManager.CreateAsync(role);
_logger.LogInformation($"创建角色:{roleName}");
}
}
/// <summary>
/// 初始化用户数据
/// </summary>
private async Task SeedUsersAsync()
{
// 查找超级管理员角色
var superAdminRole = await _identityRoleManager.FindByNameAsync("超级管理员");
if (superAdminRole == null)
{
_logger.LogError("未找到超级管理员角色,无法为用户分配角色");
return;
}
// 创建用户数据(使用固定用户名避免生成问题)
await CreateUserIfNotExistsAsync("user1", "user1", "超级管理员");
await CreateUserIfNotExistsAsync("user2", "user2", "超级管理员");
await CreateUserIfNotExistsAsync("user3", "user3", "超级管理员");
await CreateUserIfNotExistsAsync("user4", "user4", "超级管理员");
}
/// <summary>
/// 创建用户(如果不存在)
/// </summary>
private async Task CreateUserIfNotExistsAsync(
string name,
string userName,
string roles)
{
// 检查用户是否已存在
var existingUser = await _userRepository.FindAsync(u => u.NickName == name);
if (existingUser != null)
{
_logger.LogInformation($"用户[{name}]已存在,跳过创建");
return;
}
var identityUser = await _identityUserManager.FindByNameAsync(userName);
if (identityUser == null)
{
// 创建Identity用户
identityUser = new IdentityUser(
_guidGenerator.Create(),
userName,
$"{userName}@example.com",
_currentTenant.Id)
{
Name = name,
Surname = ""
};
// 设置默认密码 123456
var identityResult = await _identityUserManager.CreateAsync(identityUser, "123456");
if (!identityResult.Succeeded)
{
_logger.LogError($"创建Identity用户[{name}]失败: {string.Join(", ", identityResult.Errors.Select(e => e.Description))}");
return;
}
// 分配角色
if (!string.IsNullOrWhiteSpace(roles))
{
var roleNames = roles.Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var roleName in roleNames)
{
var trimmedRoleName = roleName.Trim();
var role = await _identityRoleManager.FindByNameAsync(trimmedRoleName);
if (role != null)
{
var roleResult = await _identityUserManager.AddToRoleAsync(identityUser, trimmedRoleName);
if (!roleResult.Succeeded)
{
_logger.LogWarning($"为用户[{name}]分配角色[{trimmedRoleName}]失败: {string.Join(", ", roleResult.Errors.Select(e => e.Description))}");
}
}
else
{
_logger.LogWarning($"角色[{trimmedRoleName}]不存在,无法为用户[{name}]分配");
}
}
}
// 创建系统用户
var user = new User(
_guidGenerator.Create(),
name,
identityUser.Id);
// 保存用户
await _userRepository.InsertAsync(user);
_logger.LogInformation($"创建用户:{name},用户名:{userName}");
}
else
{
_logger.LogInformation($"Identity用户[{userName}]已存在,检查是否需要创建业务用户");
// 检查是否需要创建业务用户
var businessUser = await _userRepository.FindAsync(u => u.IdentityUserId == identityUser.Id);
if (businessUser == null)
{
// 创建系统用户
var user = new User(
_guidGenerator.Create(),
name,
identityUser.Id);
// 保存用户
await _userRepository.InsertAsync(user);
_logger.LogInformation($"为已存在的Identity用户创建业务用户:{name}");
}
}
}
}
}

6
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs

@ -13,6 +13,12 @@ public class ProjectNamePermissionDefinitionProvider : PermissionDefinitionProvi
group.AddPermission(
ProjectNamePermissions.ManageSettings,
L("Permission:ManageSettings"));
var userPermission = group.AddPermission(ProjectNamePermissions.User.Default, L("Permission:User"));
userPermission.AddChild(ProjectNamePermissions.User.Create, L("Permission:Create"));
userPermission.AddChild(ProjectNamePermissions.User.Update, L("Permission:Update"));
userPermission.AddChild(ProjectNamePermissions.User.Delete, L("Permission:Delete"));
}
private static LocalizableString L(string name)

8
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs

@ -5,4 +5,12 @@ public static class ProjectNamePermissions
public const string GroupName = "ProjectName";
public const string ManageSettings = GroupName + ".ManageSettings";
public class User
{
public const string Default = GroupName + ".User";
public const string Update = Default + ".Update";
public const string Create = Default + ".Create";
public const string Delete = Default + ".Delete";
}
}

37
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/CreateUpdateUserDto.cs

@ -0,0 +1,37 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace PackageName.CompanyName.ProjectName.Users.Dtos
{
[Serializable]
public class CreateUpdateUserDto
{
/// <summary>
/// 用户名称
/// </summary>
[Required(ErrorMessage = "用户名称不能为空")]
[StringLength(50, ErrorMessage = "用户名称长度不能超过50个字符")]
public string NickName { get; set; }
/// <summary>
/// 密码
/// </summary>
[StringLength(20, MinimumLength = 6, ErrorMessage = "密码长度必须在6-20个字符之间")]
public string Password { get; set; }
/// <summary>
/// 联系方式
/// </summary>
public string ContactInfo { get; set; }
/// <summary>
/// 职位
/// </summary>
public string Position { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool IsActive { get; set; } = true;
}
}

39
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/UserDto.cs

@ -0,0 +1,39 @@
using System;
using Volo.Abp.Application.Dtos;
namespace PackageName.CompanyName.ProjectName.Users.Dtos
{
[Serializable]
public class UserDto : FullAuditedEntityDto<Guid>
{
/// <summary>
/// 用户名称
/// </summary>
public string NickName { get; set; }
/// <summary>
/// Identity用户Id
/// </summary>
public Guid IdentityUserId { get; set; }
/// <summary>
/// 用户状态
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// 联系方式
/// </summary>
public string ContactInfo { get; set; }
/// <summary>
/// 职位
/// </summary>
public string Position { get; set; }
/// <summary>
/// 角色名称
/// </summary>
public string RoleNames { get; set; }
}
}

39
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/UserItemDto.cs

@ -0,0 +1,39 @@
using System;
using Volo.Abp.Application.Dtos;
namespace PackageName.CompanyName.ProjectName.Users.Dtos
{
[Serializable]
public class UserItemDto : FullAuditedEntityDto<Guid>
{
/// <summary>
/// 用户名称
/// </summary>
public string NickName { get; set; }
/// <summary>
/// Identity用户Id
/// </summary>
public Guid IdentityUserId { get; set; }
/// <summary>
/// 用户状态
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// 联系方式
/// </summary>
public string ContactInfo { get; set; }
/// <summary>
/// 职位
/// </summary>
public string Position { get; set; }
/// <summary>
/// 角色名称
/// </summary>
public string RoleNames { get; set; }
}
}

14
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/Dtos/UserPagedAndSortedResultRequestDto.cs

@ -0,0 +1,14 @@
using System;
using Volo.Abp.Application.Dtos;
namespace PackageName.CompanyName.ProjectName.Users.Dtos
{
[Serializable]
public class UserPagedAndSortedResultRequestDto : PagedAndSortedResultRequestDto
{
/// <summary>
/// 用户名称
/// </summary>
public string NickName { get; set; }
}
}

55
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Users/IUserAppService.cs

@ -0,0 +1,55 @@
using PackageName.CompanyName.ProjectName.Users.Dtos;
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// 用户应用服务接口
/// </summary>
public interface IUserAppService :
IApplicationService
{
/// <summary>
/// 创建用户
/// </summary>
Task<UserDto> CreateAsync(CreateUpdateUserDto input);
/// <summary>
/// 更新用户
/// </summary>
Task<UserDto> UpdateAsync(Guid id, CreateUpdateUserDto input);
/// <summary>
/// 删除用户
/// </summary>
Task DeleteAsync(Guid id);
/// <summary>
/// 获取用户
/// </summary>
Task<UserDto> GetAsync(Guid id);
/// <summary>
/// 获取用户列表
/// </summary>
Task<PagedResultDto<UserItemDto>> GetListAsync(UserPagedAndSortedResultRequestDto input);
/// <summary>
/// 修改用户密码
/// </summary>
Task ChangePasswordAsync(Guid id, string currentPassword, string newPassword);
/// <summary>
/// 重置用户密码(管理员操作)
/// </summary>
Task ResetPasswordAsync(Guid id, string newPassword);
/// <summary>
/// 启用或禁用用户
/// </summary>
Task SetUserActiveStatusAsync(Guid id, bool isActive);
}
}

1
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj

@ -14,6 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.BackgroundJobs" />
<PackageReference Include="Volo.Abp.Ddd.Application" />
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application" />
</ItemGroup>

10
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs

@ -1,4 +1,6 @@
using AutoMapper;
using PackageName.CompanyName.ProjectName.Users;
using PackageName.CompanyName.ProjectName.Users.Dtos;
namespace PackageName.CompanyName.ProjectName;
@ -6,5 +8,13 @@ public class ProjectNameApplicationMapperProfile : Profile
{
public ProjectNameApplicationMapperProfile()
{
CreateMap<User, UserDto>()
.ForMember(d => d.IsActive, o => o.Ignore())
.ForMember(d => d.RoleNames, o => o.Ignore());
CreateMap<User, UserItemDto>()
.ForMember(d => d.IsActive, o => o.Ignore())
.ForMember(d => d.RoleNames, o => o.Ignore());
CreateMap<CreateUpdateUserDto, User>(MemberList.None);
}
}

2
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs

@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.AutoMapper;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Modularity;
namespace PackageName.CompanyName.ProjectName;
@ -12,6 +13,7 @@ namespace PackageName.CompanyName.ProjectName;
typeof(AbpDddApplicationModule),
typeof(ProjectNameDomainModule),
typeof(ProjectNameApplicationContractsModule),
typeof(AbpBackgroundJobsModule),
typeof(AbpDynamicQueryableApplicationModule))]
public class ProjectNameApplicationModule : AbpModule
{

211
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/Users/UserAppService.cs

@ -0,0 +1,211 @@
using Microsoft.AspNetCore.Authorization;
using PackageName.CompanyName.ProjectName.Permissions;
using PackageName.CompanyName.ProjectName.Users.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Identity;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// 用户
/// </summary>
public class UserAppService : ApplicationService, IUserAppService
{
private readonly IUserRepository _userRepository;
private readonly IUserManager _userManager;
private readonly IdentityUserManager _identityUserManager;
public UserAppService(
IUserRepository userRepository,
IUserManager userManager,
IdentityUserManager identityUserManager)
{
_userRepository = userRepository;
_userManager = userManager;
_identityUserManager = identityUserManager;
}
/// <summary>
/// 创建用户
/// </summary>
[Authorize(ProjectNamePermissions.User.Create)]
public async Task<UserDto> CreateAsync(CreateUpdateUserDto input)
{
// 参数检查和验证逻辑可以在这里添加
if (string.IsNullOrEmpty(input.NickName))
{
throw new UserFriendlyException("昵称不能为空");
}
if (string.IsNullOrEmpty(input.Password))
{
throw new UserFriendlyException("密码不能为空");
}
// 使用UserManager创建用户
var user = await _userManager.CreateAsync(
input.NickName,
input.Password,
input.ContactInfo,
input.Position,
input.IsActive);
// 返回DTO对象
return await MapToUserDtoAsync(user);
}
/// <summary>
/// 更新用户
/// </summary>
[Authorize(ProjectNamePermissions.User.Update)]
public async Task<UserDto> UpdateAsync(Guid id, CreateUpdateUserDto input)
{
// 使用UserManager更新用户基本信息
var user = await _userManager.UpdateAsync(
id,
input.NickName,
input.Password,
input.ContactInfo,
input.Position,
input.IsActive);
// 确保更新后的用户状态与DTO中的一致
if (user.IdentityUser != null)
{
bool currentIsActive = user.IdentityUser.LockoutEnd == null || user.IdentityUser.LockoutEnd < DateTimeOffset.Now;
if (currentIsActive != input.IsActive)
{
await _userManager.SetUserActiveStatusAsync(id, input.IsActive);
user = await _userManager.GetAsync(id);
}
}
// 返回DTO对象
return await MapToUserDtoAsync(user);
}
/// <summary>
/// 删除用户
/// </summary>
[Authorize(ProjectNamePermissions.User.Delete)]
public Task DeleteAsync(Guid id)
{
return _userManager.DeleteAsync(id);
}
/// <summary>
/// 获取用户
/// </summary>
[Authorize(ProjectNamePermissions.User.Default)]
public async Task<UserDto> GetAsync(Guid id)
{
var user = await _userManager.GetAsync(id);
return await MapToUserDtoAsync(user);
}
/// <summary>
/// 获取用户列表
/// </summary>
[Authorize(ProjectNamePermissions.User.Default)]
public async Task<PagedResultDto<UserItemDto>> GetListAsync(UserPagedAndSortedResultRequestDto input)
{
// 创建查询
var query = await CreateFilteredQueryAsync(input);
// 获取总记录数
var totalCount = await AsyncExecuter.CountAsync(query);
// 获取已排序和分页的查询结果
var users = await AsyncExecuter.ToListAsync(
query.OrderBy(input.Sorting ?? nameof(User.NickName))
.Skip(input.SkipCount)
.Take(input.MaxResultCount));
// 转换为DTO并返回
var userDtos = new List<UserItemDto>();
foreach (var user in users)
{
var userDto = ObjectMapper.Map<User, UserItemDto>(user);
// 填充角色信息
if (user.IdentityUser != null)
{
var roles = await _identityUserManager.GetRolesAsync(user.IdentityUser);
userDto.RoleNames = string.Join("、", roles);
userDto.IsActive = user.IdentityUser.LockoutEnd == null || user.IdentityUser.LockoutEnd < DateTimeOffset.Now;
}
userDtos.Add(userDto);
}
return new PagedResultDto<UserItemDto>(totalCount, userDtos);
}
/// <summary>
/// 修改用户密码
/// </summary>
[Authorize]
public async Task ChangePasswordAsync(Guid id, string currentPassword, string newPassword)
{
await _userManager.ChangePasswordAsync(id, currentPassword, newPassword);
}
/// <summary>
/// 重置用户密码(管理员操作)
/// </summary>
[Authorize(ProjectNamePermissions.User.Update)]
public async Task ResetPasswordAsync(Guid id, string newPassword)
{
await _userManager.ResetPasswordAsync(id, newPassword);
}
/// <summary>
/// 启用或禁用用户
/// </summary>
[Authorize(ProjectNamePermissions.User.Update)]
public async Task SetUserActiveStatusAsync(Guid id, bool isActive)
{
await _userManager.SetUserActiveStatusAsync(id, isActive);
}
/// <summary>
/// 创建基础查询,应用过滤条件
/// </summary>
protected async virtual Task<IQueryable<User>> CreateFilteredQueryAsync(
UserPagedAndSortedResultRequestDto input)
{
// 获取基础查询,并加载相关实体
var query = await _userRepository.WithDetailsAsync(
x => x.IdentityUser);
// 应用过滤条件
return query
.WhereIf(!string.IsNullOrWhiteSpace(input.NickName),
x => x.NickName.Contains(input.NickName));
}
/// <summary>
/// 将User实体映射为UserDto,并填充权限信息
/// </summary>
private async Task<UserDto> MapToUserDtoAsync(User user)
{
var userDto = ObjectMapper.Map<User, UserDto>(user);
// 设置用户状态和角色信息
if (user.IdentityUser != null)
{
var roles = await _identityUserManager.GetRolesAsync(user.IdentityUser);
userDto.RoleNames = string.Join("、", roles);
userDto.IsActive = user.IdentityUser.LockoutEnd == null || user.IdentityUser.LockoutEnd < DateTimeOffset.Now;
}
return userDto;
}
}
}

4
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj

@ -14,10 +14,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LINGYUN.Abp.Identity.Domain" />
<PackageReference Include="Volo.Abp.AutoMapper" />
<PackageReference Include="Volo.Abp.BackgroundJobs.Abstractions" />
<PackageReference Include="Volo.Abp.BackgroundWorkers.Hangfire" />
<PackageReference Include="Volo.Abp.Caching" />
<PackageReference Include="Volo.Abp.Ddd.Domain" />
<PackageReference Include="LINGYUN.Abp.DataProtection" />
<PackageReference Include="Volo.Abp.Settings" />
</ItemGroup>
<ItemGroup>

4
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs

@ -1,7 +1,9 @@
using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.Identity;
using Microsoft.Extensions.DependencyInjection;
using PackageName.CompanyName.ProjectName.ObjectExtending;
using Volo.Abp.AutoMapper;
using Volo.Abp.BackgroundWorkers.Hangfire;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending.Modularity;
@ -12,6 +14,8 @@ namespace PackageName.CompanyName.ProjectName;
[DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpDataProtectionModule),
typeof(AbpIdentityDomainModule),
typeof(AbpBackgroundWorkersHangfireModule),
typeof(ProjectNameDomainSharedModule))]
public class ProjectNameDomainModule : AbpModule
{

21
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/TreeCodes/IHaveTreeCode.cs

@ -0,0 +1,21 @@
using System;
using Volo.Abp.Auditing;
namespace PackageName.CompanyName.ProjectName.TreeCodes
{
/// <summary>
/// 定义具有树形编码的实体接口
/// </summary>
public interface IHaveTreeCode : IHasCreationTime
{
/// <summary>
/// 树形编码
/// </summary>
string TreeCode { get; set; }
/// <summary>
/// 父级Id
/// </summary>
Guid? ParentId { get; set; }
}
}

33
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/TreeCodes/ITreeCodeGenerator.cs

@ -0,0 +1,33 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
namespace PackageName.CompanyName.ProjectName.TreeCodes
{
/// <summary>
/// 树形编码生成器接口
/// </summary>
public interface ITreeCodeGenerator
{
/// <summary>
/// 生成树形编码
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <param name="repository">仓储</param>
/// <param name="parentId">父级Id</param>
/// <returns>生成的树形编码</returns>
Task<string> GenerateAsync<TEntity>(
IRepository<TEntity, Guid> repository,
Guid? parentId)
where TEntity : class, IEntity<Guid>, IHaveTreeCode;
/// <summary>
/// 更新节点及其所有子节点的TreeCode
/// </summary>
Task UpdateTreeCodesAsync<TEntity>(
IRepository<TEntity, Guid> repository,
Guid entityId)
where TEntity : class, IEntity<Guid>, IHaveTreeCode;
}
}

114
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/TreeCodes/TreeCodeGenerator.cs

@ -0,0 +1,114 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
namespace PackageName.CompanyName.ProjectName.TreeCodes
{
/// <summary>
/// 树形编码生成器
/// </summary>
public class TreeCodeGenerator : ITreeCodeGenerator, ISingletonDependency
{
/// <summary>
/// 生成树形编码
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <param name="repository">仓储</param>
/// <param name="parentId">父级Id</param>
/// <returns>生成的树形编码</returns>
public async virtual Task<string> GenerateAsync<TEntity>(
IRepository<TEntity, Guid> repository,
Guid? parentId)
where TEntity : class, IEntity<Guid>, IHaveTreeCode
{
if (!parentId.HasValue)
{
// 生成根节点编码
return await GenerateRootCodeAsync(repository);
}
else
{
// 生成子节点编码
return await GenerateChildCodeAsync(repository, parentId.Value);
}
}
private async Task<string> GenerateRootCodeAsync<TEntity>(
IRepository<TEntity, Guid> repository)
where TEntity : class, IEntity<Guid>, IHaveTreeCode
{
var query = await repository.GetQueryableAsync();
query = query.Where(e => e.ParentId == null).OrderByDescending(e => e.CreationTime);
var maxCodeEntity = await repository.AsyncExecuter.FirstOrDefaultAsync(query);
if (maxCodeEntity == null)
{
return "0001";
}
int maxCode = int.Parse(maxCodeEntity.TreeCode.Split('.').LastOrDefault("0"));
return (maxCode + 1).ToString("D4");
}
private async Task<string> GenerateChildCodeAsync<TEntity>(
IRepository<TEntity, Guid> repository,
Guid parentId)
where TEntity : class, IEntity<Guid>, IHaveTreeCode
{
var parent = await repository.GetAsync(parentId);
if (parent == null)
{
throw new EntityNotFoundException(typeof(TEntity), parentId);
}
var query = await repository.GetQueryableAsync();
query = query.Where(e => e.ParentId == parentId).OrderByDescending(e => e.CreationTime);
var maxCodeEntity = await repository.AsyncExecuter.FirstOrDefaultAsync(query);
string newCode;
if (maxCodeEntity == null)
{
newCode = "0001";
}
else
{
int maxCode = int.Parse(maxCodeEntity.TreeCode.Split('.').Last());
newCode = (maxCode + 1).ToString("D4");
}
// 构建完整的TreeCode: 父TreeCode.新编码
return $"{parent.TreeCode}.{newCode}";
}
/// <summary>
/// 更新节点及其所有子节点的TreeCode
/// </summary>
public async virtual Task UpdateTreeCodesAsync<TEntity>(
IRepository<TEntity, Guid> repository,
Guid entityId)
where TEntity : class, IEntity<Guid>, IHaveTreeCode
{
var entity = await repository.GetAsync(entityId);
var query = await repository.GetQueryableAsync();
var children = await repository.AsyncExecuter.ToListAsync(
query.Where(e => e.ParentId == entityId));
foreach (var child in children)
{
// 获取子节点编码(TreeCode最后一部分)或生成新编码
string childCode = child.TreeCode.Contains('.')
? child.TreeCode.Split('.').Last()
: child.TreeCode;
child.TreeCode = $"{entity.TreeCode}.{childCode}";
await repository.UpdateAsync(child);
// 递归更新子节点
await UpdateTreeCodesAsync(repository, child.Id);
}
}
}
}

69
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/IUserManager.cs

@ -0,0 +1,69 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// 用户管理服务接口
/// </summary>
public interface IUserManager : IDomainService
{
/// <summary>
/// 创建新用户
/// </summary>
Task<User> CreateAsync(
string nickName,
string password,
string contactInfo = null,
string position = null,
bool isActive = true
);
/// <summary>
/// 更新用户信息
/// </summary>
Task<User> UpdateAsync(
Guid id,
string nickName,
string password,
string contactInfo = null,
string position = null,
bool isActive = true);
/// <summary>
/// 删除用户
/// </summary>
Task DeleteAsync(Guid id);
/// <summary>
/// 修改用户密码
/// </summary>
Task ChangePasswordAsync(Guid id, string currentPassword, string newPassword);
/// <summary>
/// 重置用户密码
/// </summary>
Task ResetPasswordAsync(Guid id, string newPassword);
/// <summary>
/// 获取用户信息
/// </summary>
Task<User> GetAsync(Guid id);
/// <summary>
/// 根据Identity用户ID获取用户
/// </summary>
Task<User> FindByIdentityUserIdAsync(Guid identityUserId);
/// <summary>
/// 根据用户昵称查找用户
/// </summary>
Task<User> FindByNickNameAsync(string nickName);
/// <summary>
/// 禁用或启用用户
/// </summary>
Task SetUserActiveStatusAsync(Guid id, bool isActive);
}
}

9
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/IUserRepository.cs

@ -0,0 +1,9 @@
using System;
using Volo.Abp.Domain.Repositories;
namespace PackageName.CompanyName.ProjectName.Users
{
public interface IUserRepository : IRepository<User, Guid>
{
}
}

59
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/User.cs

@ -0,0 +1,59 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Identity;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// 用户实体
/// </summary>
public class User : FullAuditedEntity<Guid>
{
/// <summary>
/// 用户名称
/// </summary>
[MaxLength(50)]
public string NickName { get; set; }
/// <summary>
/// Identity用户Id
/// </summary>
public Guid IdentityUserId { get; set; }
/// <summary>
/// Identity用户
/// </summary>
public virtual IdentityUser IdentityUser { get; set; }
/// <summary>
/// 联系方式
/// </summary>
[MaxLength(50)]
public string ContactInfo { get; set; }
/// <summary>
/// 职位
/// </summary>
[MaxLength(50)]
public string Position { get; set; }
protected User()
{
}
public User(
Guid id,
string nickName,
Guid identityUserId,
string contactInfo = null,
string position = null
) : base(id)
{
NickName = nickName;
IdentityUserId = identityUserId;
ContactInfo = contactInfo;
Position = position;
}
}
}

449
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Users/UserManager.cs

@ -0,0 +1,449 @@
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;
using Volo.Abp.Identity;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// 用户管理服务,用于处理用户的CRUD操作
/// </summary>
public class UserManager : DomainService, IUserManager
{
private readonly IUserRepository _userRepository;
private readonly IdentityUserManager _identityUserManager;
private readonly ILogger<UserManager> _logger;
public UserManager(
IUserRepository userRepository,
IdentityUserManager identityUserManager,
ILogger<UserManager> logger)
{
_userRepository = userRepository;
_identityUserManager = identityUserManager;
_logger = logger;
}
/// <summary>
/// 创建新用户
/// </summary>
/// <param name="nickName">用户昵称</param>
/// <param name="password">用户密码</param>
/// <param name="contactInfo">联系方式</param>
/// <param name="position">职位</param>
/// <param name="isActive">是否启用</param>
/// <returns>创建的用户实体</returns>
public async Task<User> CreateAsync(
string nickName,
string password,
string contactInfo = null,
string position = null,
bool isActive = true)
{
// 参数验证
if (string.IsNullOrWhiteSpace(nickName))
{
throw new UserFriendlyException("用户名不能为空");
}
// 密码校验
if (string.IsNullOrWhiteSpace(password) || password.Length < 6)
{
throw new UserFriendlyException("密码不能为空且长度不能少于6位");
}
// 检查用户昵称是否已存在
var existingUser = await _userRepository.FindAsync(u => u.NickName == nickName);
if (existingUser != null)
{
throw new UserFriendlyException($"昵称为 '{nickName}' 的用户已存在");
}
// 创建Identity用户
var identityUser = new IdentityUser(GuidGenerator.Create(), nickName, $"{nickName}@inspection.com");
var identityResult = await _identityUserManager.CreateAsync(identityUser, password);
if (!identityResult.Succeeded)
{
throw new UserFriendlyException("创建用户失败: " +
string.Join(", ", identityResult.Errors.Select(x => x.Description)));
}
// 设置用户状态
if (!isActive)
{
var lockoutResult = await _identityUserManager.SetLockoutEndDateAsync(identityUser, DateTimeOffset.MaxValue);
if (!lockoutResult.Succeeded)
{
throw new UserFriendlyException("设置用户状态失败: " +
string.Join(", ", lockoutResult.Errors.Select(e => e.Description)));
}
}
else
{
// 确保用户处于活动状态
await _identityUserManager.SetLockoutEnabledAsync(identityUser, false);
var lockoutResult = await _identityUserManager.SetLockoutEndDateAsync(identityUser, null);
if (!lockoutResult.Succeeded)
{
throw new UserFriendlyException("设置用户状态失败: " +
string.Join(", ", lockoutResult.Errors.Select(e => e.Description)));
}
}
// 创建业务用户
var user = new User(
GuidGenerator.Create(),
nickName,
identityUser.Id,
contactInfo,
position
);
// 保存用户
await _userRepository.InsertAsync(user, true);
_logger.LogInformation($"创建了新用户:{nickName},ID:{user.Id}");
return user;
}
/// <summary>
/// 更新用户信息
/// </summary>
/// <param name="id">用户ID</param>
/// <param name="nickName">用户昵称</param>
/// <param name="password">用户密码(可选,如不修改则传入null)</param>
/// <param name="contactInfo">联系方式</param>
/// <param name="position">职位</param>
/// <param name="isActive">是否启用</param>
/// <returns>更新后的用户实体</returns>
public async Task<User> UpdateAsync(
Guid id,
string nickName,
string password,
string contactInfo = null,
string position = null,
bool isActive = true)
{
// 最大重试次数
const int maxRetries = 3;
int retryCount = 0;
while (true)
{
try
{
// 每次尝试时重新获取最新的用户数据
var user = await _userRepository.GetAsync(id, false);
if (user == null)
{
throw new UserFriendlyException("用户不存在");
}
// 检查用户昵称是否已被其他用户使用
var existingUser = await _userRepository.FindAsync(u => u.NickName == nickName && u.Id != id);
if (existingUser != null)
{
throw new UserFriendlyException($"昵称为 '{nickName}' 的用户已存在");
}
// 更新Identity用户
var identityUser = await _identityUserManager.FindByIdAsync(user.IdentityUserId.ToString());
if (identityUser == null)
{
throw new UserFriendlyException("Identity用户不存在");
}
// 更新用户名
var usernameResult = await _identityUserManager.SetUserNameAsync(identityUser, nickName);
if (!usernameResult.Succeeded)
{
throw new UserFriendlyException("更新用户名失败: " +
string.Join(", ", usernameResult.Errors.Select(e => e.Description)));
}
// 更新电子邮件
var emailResult = await _identityUserManager.SetEmailAsync(identityUser, $"{nickName}@inspection.com");
if (!emailResult.Succeeded)
{
throw new UserFriendlyException("更新电子邮件失败: " +
string.Join(", ", emailResult.Errors.Select(e => e.Description)));
}
// 如果提供了新密码,则更新密码
if (!string.IsNullOrEmpty(password))
{
// 移除当前密码
await _identityUserManager.RemovePasswordAsync(identityUser);
// 设置新密码
var passwordResult = await _identityUserManager.AddPasswordAsync(identityUser, password);
if (!passwordResult.Succeeded)
{
throw new UserFriendlyException("更新密码失败: " +
string.Join(", ", passwordResult.Errors.Select(e => e.Description)));
}
}
// 设置用户状态
await SetUserActiveStatusAsync(id, isActive);
// 更新用户信息
user.NickName = nickName;
user.ContactInfo = contactInfo;
user.Position = position;
// 保存更新
await _userRepository.UpdateAsync(user, true);
_logger.LogInformation($"更新了用户信息:{nickName},ID:{user.Id}");
return user;
}
catch (Volo.Abp.Data.AbpDbConcurrencyException ex)
{
// 增加重试计数
retryCount++;
// 如果达到最大重试次数,则抛出用户友好的异常
if (retryCount >= maxRetries)
{
throw new UserFriendlyException(
"更新用户信息失败:数据已被其他用户修改。请刷新页面后重试。",
"409", ex.Message,
ex);
}
// 短暂延迟后重试
await Task.Delay(100 * retryCount); // 逐步增加延迟时间
// 记录重试信息
_logger.LogWarning($"检测到用户[{id}]更新时发生并发冲突,正在进行第{retryCount}次重试...");
}
}
}
/// <summary>
/// 删除用户
/// </summary>
/// <param name="id">用户ID</param>
/// <returns>操作任务</returns>
public async Task DeleteAsync(Guid id)
{
// 最大重试次数
const int maxRetries = 3;
int retryCount = 0;
while (true)
{
try
{
// 每次尝试时重新获取最新的用户数据
var user = await _userRepository.GetAsync(id);
if (user == null)
{
_logger.LogWarning($"尝试删除不存在的用户,ID:{id}");
return; // 如果用户不存在,就不再继续处理
}
// 删除Identity用户
var identityUser = await _identityUserManager.FindByIdAsync(user.IdentityUserId.ToString());
if (identityUser != null)
{
var result = await _identityUserManager.DeleteAsync(identityUser);
if (!result.Succeeded)
{
throw new UserFriendlyException("删除Identity用户失败: " +
string.Join(", ", result.Errors.Select(e => e.Description)));
}
}
// 删除用户
await _userRepository.DeleteAsync(user);
_logger.LogInformation($"删除了用户,ID:{id}");
return;
}
catch (Volo.Abp.Data.AbpDbConcurrencyException ex)
{
// 增加重试计数
retryCount++;
// 如果达到最大重试次数,则抛出用户友好的异常
if (retryCount >= maxRetries)
{
throw new UserFriendlyException(
"删除用户失败:数据已被其他用户修改。请刷新页面后重试。",
"409", ex.Message,
ex);
}
// 短暂延迟后重试
await Task.Delay(100 * retryCount); // 逐步增加延迟时间
// 记录重试信息
_logger.LogWarning($"检测到用户[{id}]删除时发生并发冲突,正在进行第{retryCount}次重试...");
}
}
}
/// <summary>
/// 修改用户密码
/// </summary>
/// <param name="id">用户ID</param>
/// <param name="currentPassword">当前密码</param>
/// <param name="newPassword">新密码</param>
/// <returns>操作结果</returns>
public async Task ChangePasswordAsync(Guid id, string currentPassword, string newPassword)
{
if (string.IsNullOrEmpty(newPassword) || newPassword.Length < 6)
{
throw new UserFriendlyException("新密码不能为空且长度不能少于6位");
}
// 获取用户
var user = await _userRepository.GetAsync(id);
if (user == null)
{
throw new UserFriendlyException("用户不存在");
}
// 获取Identity用户
var identityUser = await _identityUserManager.FindByIdAsync(user.IdentityUserId.ToString());
if (identityUser == null)
{
throw new UserFriendlyException("Identity用户不存在");
}
// 修改密码
var result = await _identityUserManager.ChangePasswordAsync(identityUser, currentPassword, newPassword);
if (!result.Succeeded)
{
throw new UserFriendlyException("修改密码失败: " +
string.Join(", ", result.Errors.Select(e => e.Description)));
}
_logger.LogInformation($"用户[{user.NickName}]成功修改了密码");
}
/// <summary>
/// 重置用户密码(管理员操作)
/// </summary>
/// <param name="id">用户ID</param>
/// <param name="newPassword">新密码</param>
/// <returns>操作结果</returns>
public async Task ResetPasswordAsync(Guid id, string newPassword)
{
if (string.IsNullOrEmpty(newPassword) || newPassword.Length < 6)
{
throw new UserFriendlyException("新密码不能为空且长度不能少于6位");
}
// 获取用户
var user = await _userRepository.GetAsync(id);
if (user == null)
{
throw new UserFriendlyException("用户不存在");
}
// 获取Identity用户
var identityUser = await _identityUserManager.FindByIdAsync(user.IdentityUserId.ToString());
if (identityUser == null)
{
throw new UserFriendlyException("Identity用户不存在");
}
// 生成重置令牌
var token = await _identityUserManager.GeneratePasswordResetTokenAsync(identityUser);
// 重置密码
var result = await _identityUserManager.ResetPasswordAsync(identityUser, token, newPassword);
if (!result.Succeeded)
{
throw new UserFriendlyException("重置密码失败: " +
string.Join(", ", result.Errors.Select(e => e.Description)));
}
_logger.LogInformation($"管理员重置了用户[{user.NickName}]的密码");
}
/// <summary>
/// 获取用户信息
/// </summary>
/// <param name="id">用户ID</param>
/// <returns>用户实体</returns>
public async Task<User> GetAsync(Guid id)
{
return await _userRepository.GetAsync(id);
}
/// <summary>
/// 根据Identity用户ID获取用户
/// </summary>
/// <param name="identityUserId">Identity用户ID</param>
/// <returns>用户实体,如果不存在则返回null</returns>
public async Task<User> FindByIdentityUserIdAsync(Guid identityUserId)
{
return await _userRepository.FindAsync(u => u.IdentityUserId == identityUserId);
}
/// <summary>
/// 根据用户昵称查找用户
/// </summary>
/// <param name="nickName">用户昵称</param>
/// <returns>用户实体,如果不存在则返回null</returns>
public async Task<User> FindByNickNameAsync(string nickName)
{
return await _userRepository.FindAsync(u => u.NickName == nickName);
}
/// <summary>
/// 禁用或启用用户
/// </summary>
/// <param name="id">用户ID</param>
/// <param name="isActive">是否启用</param>
/// <returns>操作任务</returns>
public async Task SetUserActiveStatusAsync(Guid id, bool isActive)
{
// 获取用户
var user = await _userRepository.GetAsync(id);
if (user == null)
{
throw new UserFriendlyException("用户不存在");
}
// 获取Identity用户
var identityUser = await _identityUserManager.FindByIdAsync(user.IdentityUserId.ToString());
if (identityUser == null)
{
throw new UserFriendlyException("Identity用户不存在");
}
// 设置用户状态
if (isActive)
{
// 启用用户
var result = await _identityUserManager.SetLockoutEndDateAsync(identityUser, null);
if (!result.Succeeded)
{
throw new UserFriendlyException($"启用用户失败: " +
string.Join(", ", result.Errors.Select(e => e.Description)));
}
}
else
{
// 禁用用户(设置永久锁定)
var result = await _identityUserManager.SetLockoutEndDateAsync(identityUser, DateTimeOffset.MaxValue);
if (!result.Succeeded)
{
throw new UserFriendlyException($"禁用用户失败: " +
string.Join(", ", result.Errors.Select(e => e.Description)));
}
}
_logger.LogInformation($"已{(isActive ? "" : "")}用户[{user.NickName}]");
}
}
}

1
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj

@ -28,6 +28,7 @@
<PackageReference Include="LINGYUN.Abp.Data.DbMigrator" />
<PackageReference Include="LINGYUN.Abp.DataProtection.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.Saas.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.Identity.EntityFrameworkCore" />
</ItemGroup>
<ItemGroup>

5
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs

@ -1,4 +1,6 @@
using Volo.Abp.Data;
using Microsoft.EntityFrameworkCore;
using PackageName.CompanyName.ProjectName.Users;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore;
@ -6,4 +8,5 @@ namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore;
[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)]
public interface IProjectNameDbContext : IEfCoreDbContext
{
DbSet<User> Users { get; }
}

13
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs

@ -1,12 +1,18 @@
using LINGYUN.Abp.DataProtection.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using PackageName.CompanyName.ProjectName.Users;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity.EntityFrameworkCore;
namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore;
[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)]
public class ProjectNameDbContext : AbpDataProtectionDbContext<ProjectNameDbContext>, IProjectNameDbContext
// public class ProjectNameDbContext : AbpDataProtectionDbContext<ProjectNameDbContext>, IProjectNameDbContext
public class ProjectNameDbContext : AbpDbContext<ProjectNameDbContext>, IProjectNameDbContext
{
public virtual DbSet<User> Users { get; set; }
public ProjectNameDbContext(
DbContextOptions<ProjectNameDbContext> options) : base(options)
{
@ -14,8 +20,9 @@ public class ProjectNameDbContext : AbpDataProtectionDbContext<ProjectNameDbCont
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ConfigureProjectName();
modelBuilder.ConfigureIdentity();
base.OnModelCreating(modelBuilder);
}
}

17
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs

@ -1,6 +1,8 @@
using Microsoft.EntityFrameworkCore;
using PackageName.CompanyName.ProjectName.Users;
using System;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore;
@ -17,5 +19,20 @@ public static class ProjectNameDbContextModelCreatingExtensions
ProjectNameDbProperties.DbSchema
);
optionsAction?.Invoke(options);
builder.Entity<User>(b =>
{
b.ToTable(ProjectNameDbProperties.DbTablePrefix + "Users", ProjectNameDbProperties.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.NickName).HasComment("用户名称");
b.Property(x => x.IdentityUserId).HasComment("Identity用户Id");
// 用户与IdentityUser的关系(一对一)
b.HasOne(x => x.IdentityUser)
.WithOne()
.HasForeignKey<User>(u => u.IdentityUserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
});
}
}

6
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs

@ -2,7 +2,9 @@
using LINGYUN.Abp.DataProtection.EntityFrameworkCore;
using LINGYUN.Abp.Saas.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using PackageName.CompanyName.ProjectName.Users;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Modularity;
#if MySQL
using Volo.Abp.EntityFrameworkCore.MySQL;
@ -38,6 +40,7 @@ namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore;
#elif PostgreSql
typeof(AbpEntityFrameworkCorePostgreSqlModule),
#endif
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpSaasEntityFrameworkCoreModule))]
public class ProjectNameEntityFrameworkCoreModule : AbpModule
{
@ -70,7 +73,8 @@ public class ProjectNameEntityFrameworkCoreModule : AbpModule
context.Services.AddAbpDbContext<ProjectNameDbContext>(options =>
{
options.AddDefaultRepositories<IProjectNameDbContext>();
options.AddDefaultRepositories<IProjectNameDbContext>(true);
options.AddRepository<User, UserRepository>();
});
}
}

22
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/Users/UserRepository.cs

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore;
using PackageName.CompanyName.ProjectName.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace PackageName.CompanyName.ProjectName.Users
{
public class UserRepository : EfCoreRepository<ProjectNameDbContext, User, Guid>, IUserRepository
{
public UserRepository(IDbContextProvider<ProjectNameDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public override async Task<IQueryable<User>> WithDetailsAsync()
{
return (await GetDbSetAsync()).Include(x => x.IdentityUser);
}
}
}

134
aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/Users/UserController.cs

@ -0,0 +1,134 @@
using Microsoft.AspNetCore.Mvc;
using PackageName.CompanyName.ProjectName.Users.Dtos;
using System;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// 用户管理控制器
/// </summary>
[RemoteService]
[Route("api/app/user")]
public class UserController : ProjectNameControllerBase
{
private readonly IUserAppService _userAppService;
public UserController(IUserAppService userAppService)
{
_userAppService = userAppService;
}
/// <summary>
/// 创建用户
/// </summary>
[HttpPost]
public async Task<UserDto> CreateAsync(CreateUpdateUserDto input)
{
return await _userAppService.CreateAsync(input);
}
/// <summary>
/// 更新用户
/// </summary>
[HttpPut("{id}")]
public async Task<UserDto> UpdateAsync(Guid id, CreateUpdateUserDto input)
{
return await _userAppService.UpdateAsync(id, input);
}
/// <summary>
/// 删除用户
/// </summary>
[HttpDelete("{id}")]
public async Task DeleteAsync(Guid id)
{
await _userAppService.DeleteAsync(id);
}
/// <summary>
/// 获取用户
/// </summary>
[HttpGet("{id}")]
public async Task<UserDto> GetAsync(Guid id)
{
return await _userAppService.GetAsync(id);
}
/// <summary>
/// 获取用户列表
/// </summary>
[HttpGet]
public async Task<PagedResultDto<UserItemDto>> GetListAsync(UserPagedAndSortedResultRequestDto input)
{
return await _userAppService.GetListAsync(input);
}
/// <summary>
/// 修改用户密码
/// </summary>
[HttpPost("{id}/change-password")]
public async Task ChangePasswordAsync(Guid id, [FromBody] ChangePasswordRequest request)
{
await _userAppService.ChangePasswordAsync(id, request.CurrentPassword, request.NewPassword);
}
/// <summary>
/// 重置用户密码(管理员操作)
/// </summary>
[HttpPost("{id}/reset-password")]
public async Task ResetPasswordAsync(Guid id, [FromBody] ResetPasswordRequest request)
{
await _userAppService.ResetPasswordAsync(id, request.NewPassword);
}
/// <summary>
/// 启用或禁用用户
/// </summary>
[HttpPost("{id}/set-active")]
public async Task SetUserActiveStatusAsync(Guid id, [FromBody] SetUserActiveRequest request)
{
await _userAppService.SetUserActiveStatusAsync(id, request.IsActive);
}
}
/// <summary>
/// 修改密码请求
/// </summary>
public class ChangePasswordRequest
{
/// <summary>
/// 当前密码
/// </summary>
public string CurrentPassword { get; set; }
/// <summary>
/// 新密码
/// </summary>
public string NewPassword { get; set; }
}
/// <summary>
/// 重置密码请求
/// </summary>
public class ResetPasswordRequest
{
/// <summary>
/// 新密码
/// </summary>
public string NewPassword { get; set; }
}
/// <summary>
/// 设置用户状态请求
/// </summary>
public class SetUserActiveRequest
{
/// <summary>
/// 是否启用
/// </summary>
public bool IsActive { get; set; }
}
}

5
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj

@ -7,12 +7,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LINGYUN.Abp.Identity.Application" />
<PackageReference Include="Volo.Abp.BackgroundJobs.HangFire" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Hangfire.MemoryStorage" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\PackageName.CompanyName.ProjectName.Application\PackageName.CompanyName.ProjectName.Application.csproj" />
<ProjectReference Include="..\PackageName.CompanyName.ProjectName.Domain.Tests\PackageName.CompanyName.ProjectName.Domain.Tests.csproj" />
<ProjectReference Include="..\PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests\PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj" />
</ItemGroup>
</Project>

137
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/DataSeeder/ProjectNameDataSeederTests.cs

@ -0,0 +1,137 @@
using Microsoft.Extensions.DependencyInjection;
using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DataSeeder;
using PackageName.CompanyName.ProjectName.Users;
using Shouldly;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Uow;
using Xunit;
namespace PackageName.CompanyName.ProjectName.DataSeeder
{
/// <summary>
/// 数据种子初始化测试
/// </summary>
[Collection("Database")]
public class ProjectNameDataSeederTests : ProjectNameApplicationTestBase
{
private readonly IProjectNameDataSeeder _inspectionDataSeeder;
private readonly IRepository<User, Guid> _userRepository;
private readonly IIdentityRoleRepository _identityRoleRepository;
private readonly IIdentityUserRepository _identityUserRepository;
public ProjectNameDataSeederTests()
{
_inspectionDataSeeder = GetRequiredService<IProjectNameDataSeeder>();
_userRepository = GetRequiredService<IRepository<User, Guid>>();
_identityRoleRepository = GetRequiredService<IIdentityRoleRepository>();
_identityUserRepository = GetRequiredService<IIdentityUserRepository>();
}
[Fact]
public async Task Should_Seed_Data_Successfully()
{
// Arrange
var context = new DataSeedContext();
// Act
await _inspectionDataSeeder.SeedAsync(context);
// Assert - 使用单元工作方法包装所有数据库操作
await WithUnitOfWorkAsync(async () =>
{
// 测试角色
var roles = await _identityRoleRepository.GetListAsync();
roles.Count.ShouldBeGreaterThanOrEqualTo(7); // 至少应该有 7 个角色
var superAdminRole = await _identityRoleRepository.FindByNormalizedNameAsync("超级管理员".ToUpperInvariant());
superAdminRole.ShouldNotBeNull();
// 测试用户
var users = await _userRepository.GetListAsync();
users.Count.ShouldBeGreaterThanOrEqualTo(10); // 至少应该有 10 个用户
foreach (var user in users)
{
user.IdentityUserId.ShouldNotBe(Guid.Empty);
var identityUser = await _identityUserRepository.GetAsync(user.IdentityUserId);
identityUser.ShouldNotBeNull();
}
return true;
});
}
[Theory]
[InlineData("超级管理员")]
[InlineData("普通用户")]
public async Task Should_Create_Roles(string roleName)
{
// Arrange
var context = new DataSeedContext();
await _inspectionDataSeeder.SeedAsync(context);
// Act & Assert - 使用单元工作方法包装
await WithUnitOfWorkAsync(async () =>
{
var role = await _identityRoleRepository.FindByNormalizedNameAsync(roleName.ToUpperInvariant());
role.ShouldNotBeNull();
role.Name.ShouldBe(roleName);
return true;
});
}
[Theory]
[InlineData("testuser1")]
[InlineData("testuser2")]
public async Task Should_Create_Users(string nickName)
{
// Arrange
var context = new DataSeedContext();
await _inspectionDataSeeder.SeedAsync(context);
// Act & Assert - 使用单元工作方法包装
await WithUnitOfWorkAsync(async () =>
{
var users = await _userRepository.GetListAsync();
var user = users.FirstOrDefault(u => u.NickName == nickName);
user.ShouldNotBeNull();
user.NickName.ShouldBe(nickName);
user.IdentityUserId.ShouldNotBe(Guid.Empty);
var identityUser = await _identityUserRepository.GetAsync(user.IdentityUserId);
identityUser.ShouldNotBeNull();
identityUser.Name.ShouldBe(nickName);
return true;
});
}
// 添加单元工作方法
protected override Task<TResult> WithUnitOfWorkAsync<TResult>(Func<Task<TResult>> func)
{
return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func);
}
// 可选:添加重载方法以支持更多场景
protected async override Task<TResult> WithUnitOfWorkAsync<TResult>(AbpUnitOfWorkOptions options, Func<Task<TResult>> func)
{
using (var scope = ServiceProvider.CreateScope())
{
var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
using (var uow = uowManager.Begin(options))
{
var result = await func();
await uow.CompleteAsync();
return result;
}
}
}
}
}

56
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs

@ -1,11 +1,65 @@
using Hangfire;
using Hangfire.MemoryStorage;
using LINGYUN.Abp.Identity;
using LINGYUN.Abp.Identity.Session;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DataSeeder;
using PackageName.CompanyName.ProjectName.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.Security.Claims;
namespace PackageName.CompanyName.ProjectName;
[DependsOn(
typeof(ProjectNameDomainTestModule),
typeof(ProjectNameApplicationModule)
typeof(ProjectNameApplicationModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpPermissionManagementDomainIdentityModule),
typeof(ProjectNameEntityFrameworkCoreTestModule)
)]
public class ProjectNameApplicationTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// //设置ILogger为NullLogger
context.Services.AddLogging(builder => builder.AddProvider(NullLoggerProvider.Instance));
context.Services.AddTransient<IProjectNameDataSeeder, ProjectNameDataSeeder>();
context.Services.AddLogging(builder => builder.AddProvider(NullLoggerProvider.Instance));
context.Services.AddTransient<IHostEnvironment, TestHostEnvironment>();
context.Services.AddTransient<IFileProvider, TestFileProvider>();
// 增加配置文件定义,在新建租户时需要
Configure<IdentityOptions>(options =>
{
// 允许中文用户名
options.User.AllowedUserNameCharacters = null;
// 支持弱密码
options.Password.RequireDigit = false;
options.Password.RequiredLength = 1;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
// 添加默认的双因素令牌提供者配置
options.Tokens.ProviderMap.Add("Default", new TokenProviderDescriptor(typeof(EmailTokenProvider<IdentityUser>)));
});
Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
Configure<IdentitySessionCleanupOptions>(options =>
{
options.IsCleanupEnabled = true;
});
// 配置Hangfire
context.Services.AddHangfire(config =>
{
config.UseMemoryStorage();
});
}
}

64
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/TestFileProvider.cs

@ -0,0 +1,64 @@
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.IO;
namespace PackageName.CompanyName.ProjectName;
public class TestFileProvider : IFileProvider
{
private readonly Dictionary<string, IFileInfo> _files;
public TestFileProvider()
{
_files = new Dictionary<string, IFileInfo>();
}
public IDirectoryContents GetDirectoryContents(string subpath)
{
return new NotFoundDirectoryContents();
}
public IFileInfo GetFileInfo(string subpath)
{
if (_files.TryGetValue(subpath, out var fileInfo))
{
return fileInfo;
}
return new NotFoundFileInfo(subpath);
}
public IChangeToken Watch(string filter)
{
return NullChangeToken.Singleton;
}
public void AddFile(string path, string contents)
{
_files[path] = new TestFileInfo(path, contents);
}
}
public class TestFileInfo : IFileInfo
{
private readonly string _contents;
public TestFileInfo(string name, string contents)
{
Name = name;
_contents = contents;
}
public bool Exists => true;
public long Length => _contents.Length;
public string PhysicalPath => null;
public string Name { get; }
public DateTimeOffset LastModified => DateTimeOffset.UtcNow;
public bool IsDirectory => false;
public Stream CreateReadStream()
{
return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(_contents));
}
}

21
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/TestHostEnvironment.cs

@ -0,0 +1,21 @@
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using System;
namespace PackageName.CompanyName.ProjectName;
public class TestHostEnvironment : IHostEnvironment
{
public TestHostEnvironment()
{
EnvironmentName = "Test";
ApplicationName = "TestApplication";
ContentRootPath = AppDomain.CurrentDomain.BaseDirectory;
ContentRootFileProvider = new PhysicalFileProvider(ContentRootPath);
}
public string EnvironmentName { get; set; }
public string ApplicationName { get; set; }
public string ContentRootPath { get; set; }
public IFileProvider ContentRootFileProvider { get; set; }
}

265
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/Users/UserAppServiceTests.cs

@ -0,0 +1,265 @@
using PackageName.CompanyName.ProjectName.Users.Dtos;
using Shouldly;
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Validation;
using Xunit;
namespace PackageName.CompanyName.ProjectName.Users
{
/// <summary>
/// UserAppService 的单元测试
/// </summary>
[Collection("Database")]
public class UserAppServiceTests : ProjectNameApplicationTestBase
{
private readonly IUserAppService _userAppService;
private readonly IUserManager _userManager;
public UserAppServiceTests()
{
_userAppService = GetRequiredService<IUserAppService>();
_userManager = GetRequiredService<IUserManager>();
}
[Theory]
[InlineData("testuser1", "Test123456!", true)]
[InlineData("testuser2", "Test123456!", false)]
public async Task Should_Create_User(
string nickName,
string password,
bool isActive)
{
// Arrange
var input = new CreateUpdateUserDto
{
NickName = nickName,
Password = password,
IsActive = isActive
};
// Act
var result = await _userAppService.CreateAsync(input);
// Assert
result.ShouldNotBeNull();
result.NickName.ShouldBe(nickName);
result.IsActive.ShouldBe(isActive);
}
[Theory]
[InlineData("", "Test123456!", "用户名称不能为空")]
[InlineData("test", "123", "密码长度必须在6-20个字符之间")]
public async Task Should_Not_Create_User_With_Invalid_Input(string nickName, string password,
string expectedErrorMessage)
{
// Arrange
var input = new CreateUpdateUserDto
{
NickName = nickName,
Password = password
};
// Act & Assert
var exception = await Assert.ThrowsAsync<AbpValidationException>(async () =>
{
await _userAppService.CreateAsync(input);
});
exception.ValidationErrors.ShouldContain(x => x.ErrorMessage.Contains(expectedErrorMessage));
}
[Fact]
public async Task Should_Get_User_List()
{
// Arrange
await CreateTestUserAsync("testuser1", "Test123456!");
await CreateTestUserAsync("testuser2", "Test123456!");
// Act
var result = await _userAppService.GetListAsync(
new UserPagedAndSortedResultRequestDto
{
MaxResultCount = 10,
SkipCount = 0,
Sorting = "NickName"
});
// Assert
result.ShouldNotBeNull();
result.TotalCount.ShouldBeGreaterThanOrEqualTo(2);
result.Items.ShouldContain(x => x.NickName == "testuser1");
result.Items.ShouldContain(x => x.NickName == "testuser2");
}
[Fact]
public async Task Should_Filter_Users_By_NickName()
{
// Arrange
await CreateTestUserAsync("testuser1", "Test123456!");
await CreateTestUserAsync("testuser2", "Test123456!");
await CreateTestUserAsync("otheruser", "Test123456!");
// Act
var result = await _userAppService.GetListAsync(
new UserPagedAndSortedResultRequestDto
{
MaxResultCount = 10,
SkipCount = 0,
Sorting = "NickName",
NickName = "testuser"
});
// Assert
result.ShouldNotBeNull();
result.TotalCount.ShouldBe(2);
result.Items.ShouldContain(x => x.NickName == "testuser1");
result.Items.ShouldContain(x => x.NickName == "testuser2");
result.Items.ShouldNotContain(x => x.NickName == "otheruser");
}
[Fact]
public async Task Should_Update_User()
{
// Arrange
var user = await CreateTestUserAsync("updatetest", "Test123456!");
var updateInput = new CreateUpdateUserDto
{
NickName = "updateduser",
Password = "NewPassword123!",
ContactInfo = "13800138000",
Position = "开发工程师",
IsActive = true
};
// Act
var result = await _userAppService.UpdateAsync(user.Id, updateInput);
// Assert
result.ShouldNotBeNull();
result.NickName.ShouldBe("updateduser");
result.ContactInfo.ShouldBe("13800138000");
result.Position.ShouldBe("开发工程师");
// 验证更新后的用户信息
var updatedUser = await _userAppService.GetAsync(user.Id);
updatedUser.NickName.ShouldBe("updateduser");
}
[Fact]
public async Task Should_Not_Update_Non_Existing_User()
{
// Arrange
var input = new CreateUpdateUserDto
{
NickName = "testuser",
Password = "Test123456!"
};
// Act & Assert
await Assert.ThrowsAsync<EntityNotFoundException>(async () =>
{
await _userAppService.UpdateAsync(Guid.NewGuid(), input);
});
}
[Fact]
public async Task Should_Delete_User()
{
// Arrange
var user = await CreateTestUserAsync("deletetest", "Test123456!");
// Act
await _userAppService.DeleteAsync(user.Id);
// Assert - 尝试获取已删除的用户应该抛出异常
await Assert.ThrowsAsync<EntityNotFoundException>(async () =>
{
await _userAppService.GetAsync(user.Id);
});
}
[Fact]
public async Task Should_Change_User_Password()
{
// Arrange
var user = await CreateTestUserAsync("passwordtest", "OldPassword123!");
// Act & Assert
await _userAppService.ChangePasswordAsync(user.Id, "OldPassword123!", "NewPassword123!");
// 尝试用新密码登录(这个需要集成测试才能完整测试)
// 这里我们只是验证方法执行不会抛出异常
}
[Fact]
public async Task Should_Reset_User_Password()
{
// Arrange
var user = await CreateTestUserAsync("resetpasswordtest", "OldPassword123!");
// Act & Assert
await _userAppService.ResetPasswordAsync(user.Id, "NewPassword123!");
// 同样,完整测试需要验证用户能用新密码登录,这需要集成测试
}
[Fact]
public async Task Should_Set_User_Active_Status()
{
// Arrange
var user = await CreateTestUserAsync("activestatustest", "Password123!");
// Act
await _userAppService.SetUserActiveStatusAsync(user.Id, false);
var disabledUser = await _userAppService.GetAsync(user.Id);
await _userAppService.SetUserActiveStatusAsync(user.Id, true);
var enabledUser = await _userAppService.GetAsync(user.Id);
// Assert
disabledUser.IsActive.ShouldBeFalse();
enabledUser.IsActive.ShouldBeTrue();
}
[Theory]
[InlineData("13900000000", "工程师")]
[InlineData("13800000000", "设计师")]
[InlineData(null, null)]
public async Task Should_Create_User_With_Optional_Fields(string contactInfo, string position)
{
// Arrange
var input = new CreateUpdateUserDto
{
NickName = $"user_{Guid.NewGuid():N}",
Password = "Test123456!",
ContactInfo = contactInfo,
Position = position
};
// Act
var result = await _userAppService.CreateAsync(input);
// Assert
result.ShouldNotBeNull();
result.ContactInfo.ShouldBe(contactInfo);
result.Position.ShouldBe(position);
}
private async Task<UserDto> CreateTestUserAsync(string nickName, string password)
{
return await WithUnitOfWorkAsync(async () =>
{
var input = new CreateUpdateUserDto
{
NickName = nickName,
Password = password,
IsActive = true
};
return await _userAppService.CreateAsync(input);
});
}
}
}

6
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj

@ -8,10 +8,14 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql" />
<PackageReference Include="LINGYUN.Abp.Identity.EntityFrameworkCore" />
<PackageReference Include="LINGYUN.Abp.DataProtection.EntityFrameworkCore" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\migrations\PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore\PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\src\PackageName.CompanyName.ProjectName.EntityFrameworkCore\PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\PackageName.CompanyName.ProjectName.Domain.Tests\PackageName.CompanyName.ProjectName.Domain.Tests.csproj" />
</ItemGroup>

62
aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs

@ -1,38 +1,74 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore;
using System;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
using Volo.Abp.Uow;
namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore;
[DependsOn(
typeof(ProjectNameTestBaseModule),
typeof(ProjectNameEntityFrameworkCoreModule)
)]
typeof(ProjectNameEntityFrameworkCoreModule),
typeof(SingleMigrationsEntityFrameworkCoreModule)
)]
public class ProjectNameEntityFrameworkCoreTestModule : AbpModule
{
// 数据库配置
private const string DefaultPostgresConnectionString =
"Host=127.0.0.1;Port=5432;Database=test_db;User Id=postgres;Password=postgres;";
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddEntityFrameworkInMemoryDatabase();
var connectionString = Environment.GetEnvironmentVariable("TEST_CONNECTION_STRING") ??
DefaultPostgresConnectionString;
var databaseName = Guid.NewGuid().ToString();
// 配置数据库连接字符串
Configure<AbpDbConnectionOptions>(options =>
{
options.ConnectionStrings.Default = connectionString;
});
Configure<AbpDbContextOptions>(options =>
Configure<AbpClockOptions>(options => { options.Kind = DateTimeKind.Utc; });
context.Services.AddAbpDbContext<SingleMigrationsDbContext>(options =>
{
options.Configure(abpDbContextConfigurationContext =>
{
abpDbContextConfigurationContext.DbContextOptions.EnableDetailedErrors();
abpDbContextConfigurationContext.DbContextOptions.EnableSensitiveDataLogging();
options.AddDefaultRepositories(true);
});
abpDbContextConfigurationContext.DbContextOptions.UseInMemoryDatabase(databaseName);
});
// 配置所有DbContext
Configure<AbpDbContextOptions>(options =>
{
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
options.UseNpgsql();
});
Configure<AbpUnitOfWorkDefaultOptions>(options =>
{
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
});
}
}
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var dbContext = context.ServiceProvider.GetRequiredService<SingleMigrationsDbContext>();
// 重置数据库
dbContext.Database.EnsureDeleted();
// // 创建数据库
dbContext.Database.EnsureCreated();
dbContext.Database.GenerateCreateScript();
// dbContext.Database.Migrate();
// 初始化种子数据
var dataSeeder = context.ServiceProvider.GetRequiredService<IDataSeeder>();
AsyncHelper.RunSync(() => dataSeeder.SeedAsync());
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
}
}
Loading…
Cancel
Save