Browse Source

Merge branch 'main' into dev

# Conflicts:
#	aspnet-core/LINGYUN.MicroService.SingleProject.sln
pull/1067/head
feijie 1 year ago
parent
commit
87b068b57b
  1. 13
      README.en.md
  2. 13
      README.md
  3. 3833
      aspnet-core/LINGYUN.MicroService.SingleProject.sln
  4. 2
      aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs
  5. 41
      aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/LocalFileCreateProjectService.cs
  6. 3
      aspnet-core/framework/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json
  7. 7
      aspnet-core/framework/cli/LINGYUN.Abp.Cli/README.zh-Hans.md
  8. 33
      aspnet-core/framework/cloud-aliyun/README.md
  9. 42
      aspnet-core/framework/cloud-tencent/README.md
  10. 59
      aspnet-core/framework/common/README.md
  11. 5
      aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj
  12. 6
      aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/SingleDbMigratorModule.cs
  13. 228
      aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.SqlServer.json
  14. 3
      aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json
  15. 5828
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.Designer.cs
  16. 183
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.cs
  17. 289
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs
  18. 16
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj
  19. 59
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.en.md
  20. 59
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.md
  21. 35
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsDbContextFactory.cs
  22. 26
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsEntityFrameworkCoreSqlServerModule.cs
  23. 200
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleDbMigrationService.cs
  24. 5
      aspnet-core/migrations/Migrate.ps1
  25. 5
      aspnet-core/migrations/MigrateEn.ps1
  26. 263
      aspnet-core/services/Directory.Packages.props
  27. 12
      aspnet-core/services/LY.AIO.Applications.Single/.config/dotnet-tools.json
  28. 2
      aspnet-core/services/LY.AIO.Applications.Single/.gitignore
  29. 89
      aspnet-core/services/LY.AIO.Applications.Single/Authentication/AbpCookieAuthenticationHandler.cs
  30. 38
      aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJob.cs
  31. 22
      aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJobArgs.cs
  32. 11
      aspnet-core/services/LY.AIO.Applications.Single/Controllers/HomeController.cs
  33. 70
      aspnet-core/services/LY.AIO.Applications.Single/Controllers/SettingMergeController.cs
  34. 45
      aspnet-core/services/LY.AIO.Applications.Single/Controllers/UserSettingMergeController.cs
  35. 19
      aspnet-core/services/LY.AIO.Applications.Single/Dockerfile
  36. 59
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/ChatMessageEventHandler.cs
  37. 470
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/NotificationEventHandler.cs
  38. 53
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs
  39. 30
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/UserCreateEventHandler.cs
  40. 112
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/WebhooksEventHandler.cs
  41. 58
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateJoinIMEventHandler.cs
  42. 69
      aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
  43. 19
      aspnet-core/services/LY.AIO.Applications.Single/IdentityResources/CustomIdentityResources.cs
  44. 272
      aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj
  45. 935
      aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs
  46. 394
      aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs
  47. 67
      aspnet-core/services/LY.AIO.Applications.Single/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs
  48. 10
      aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/ITenantConfigurationCache.cs
  49. 59
      aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCache.cs
  50. 19
      aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCacheItem.cs
  51. 103
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml
  52. 28
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js
  53. 17
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml
  54. 72
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml.cs
  55. 13
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml
  56. 22
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml.cs
  57. 26
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml
  58. 125
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml.cs
  59. 16
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml
  60. 73
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml.cs
  61. 63
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/TwoFactorSupportedLoginModel.cs
  62. 4
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml
  63. 11
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml.cs
  64. 26
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml
  65. 59
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml.cs
  66. 29
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml
  67. 90
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml.cs
  68. 36
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml
  69. 11
      aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml.cs
  70. 4
      aspnet-core/services/LY.AIO.Applications.Single/Pages/_ViewImports.cshtml
  71. 82
      aspnet-core/services/LY.AIO.Applications.Single/Program.cs
  72. 30
      aspnet-core/services/LY.AIO.Applications.Single/Properties/launchSettings.json
  73. 35
      aspnet-core/services/LY.AIO.Applications.Single/TenantHeaderParamter.cs
  74. 21
      aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/TextMessageReplyContributor.cs
  75. 21
      aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/UserSubscribeEventContributor.cs
  76. 24
      aspnet-core/services/LY.AIO.Applications.Single/WeChat/Work/Messages/TextMessageReplyContributor.cs
  77. 249
      aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json
  78. 89
      aspnet-core/services/LY.AIO.Applications.Single/appsettings.json
  79. 10
      aspnet-core/services/LY.AIO.Applications.Single/gulpfile.js
  80. 30
      aspnet-core/templates/aio/PackageName.CompanyName.ProjectName.AIO.csproj
  81. 115
      aspnet-core/templates/aio/content/.template.config/template.json
  82. 0
      aspnet-core/templates/aio/content/.template.config/template.zh-Hans.json
  83. 26
      aspnet-core/templates/aio/content/Directory.Build.props
  84. 537
      aspnet-core/templates/aio/content/Directory.Packages.props
  85. 0
      aspnet-core/templates/aio/content/NuGet.Config
  86. 135
      aspnet-core/templates/aio/content/README.md
  87. 135
      aspnet-core/templates/aio/content/README.zh-CN.md
  88. 74
      aspnet-core/templates/aio/content/common.props
  89. 0
      aspnet-core/templates/aio/content/configureawait.props
  90. 12
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json
  91. 2
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore
  92. 89
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs
  93. 38
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs
  94. 22
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs
  95. 11
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs
  96. 70
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs
  97. 45
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs
  98. 19
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile
  99. 59
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs
  100. 470
      aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs

13
README.en.md

@ -10,6 +10,19 @@ This is a [vue-vben-admin](https://github.com/anncwb/vue-vben-admin) -based Abp
[![Build](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml/badge.svg)](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml)
## Deployment Options
### Monolithic Service Deployment
If you don't need a microservices architecture, you can choose the monolithic service deployment option. Monolithic services are characterized by simple deployment and easy maintenance.
- [Monolithic Service Startup Guide](./docs/startup-aio-readme.en.md)
- [单体服务启动说明](./docs/startup-aio-readme.md)
### Microservices Deployment
If you need higher scalability and a more flexible service architecture, you can choose the microservices deployment option.
## Quick Start
### 0、Configurate hosts

13
README.md

@ -1,4 +1,3 @@
[English](./README.en.md) | 简体中文
[更新说明](./RELEASE.md) 更新说明
@ -11,6 +10,18 @@
[![Build](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml/badge.svg)](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml)
## 部署方案
### 单体服务部署
如果您不需要微服务架构,可以选择单体服务部署方案。单体服务具有部署简单、维护方便的特点。
- [单体服务启动说明](./docs/startup-aio-readme.md)
- [Monolithic Service Startup Guide](./docs/startup-aio-readme.en.md)
### 微服务部署
如果您需要更高的可扩展性和更灵活的服务架构,可以选择微服务部署方案。
## 快速搭建微服务启动项目

3833
aspnet-core/LINGYUN.MicroService.SingleProject.sln

File diff suppressed because it is too large

2
aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs

@ -196,7 +196,7 @@ namespace LINGYUN.Abp.Cli.Commands
sb.AppendLine("Options:");
sb.AppendLine("");
sb.AppendLine("-pk|--package <package-name> (default: app)");
sb.AppendLine("-t|--template <template-name> (default: lam)");
sb.AppendLine("-t|--template <template-name> (default: lam), optional:lam、laa");
sb.AppendLine("-d|--database-provider <database-provider> (if supported by the template)");
sb.AppendLine("-o|--output-folder <output-folder> (default: current folder)");
sb.AppendLine("-v|--version <version> (default: latest version)");

41
aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/LocalFileCreateProjectService.cs

@ -87,7 +87,7 @@ namespace LINGYUN.Abp.Cli.Commands
projectFiles,
createArgs.PackageName,
createArgs.SolutionName.CompanyName,
createArgs.DatabaseManagementSystem);
dbm);
Logger.LogInformation("Rewrite appsettings.json.");
await TryReplaceAppSettingsWithProjectFile(
@ -96,6 +96,13 @@ namespace LINGYUN.Abp.Cli.Commands
createArgs.SolutionName.CompanyName,
createArgs.SolutionName.ProjectName,
createArgs.ConnectionString);
// Logger.LogInformation("Rewrite scripts.");
// await TryReplaceScriptProjectFile(
// projectFiles,
// createArgs.PackageName,
// createArgs.SolutionName.CompanyName,
// dbm);
Logger.LogInformation("Rewrite application url.");
await TryReplaceApplicationUrlWithProjectFile(
@ -112,7 +119,8 @@ namespace LINGYUN.Abp.Cli.Commands
await TryReplacePackageAndCompanyNameWithProjectFolder(
projectFiles,
createArgs.PackageName,
createArgs.SolutionName.CompanyName);
createArgs.SolutionName.CompanyName,
dbm);
Logger.LogInformation($"'{createArgs.SolutionName.ProjectName}' has been successfully created to '{createArgs.OutputFolder}'");
}
@ -203,32 +211,53 @@ namespace LINGYUN.Abp.Cli.Commands
await ReplaceFileTextAsync(projectFile, defaultConnectionString, connectionString);
}
}
//
// protected async virtual Task TryReplaceScriptProjectFile(
// List<FindFile> projectFiles,
// string packageName,
// string companyName,
// string dbm = "MySQL")
// {
// var canReplaceFiles = projectFiles.Where(f => !f.IsFolder && f.Name.EndsWith(".bat", StringComparison.OrdinalIgnoreCase) ||
// f.Name.EndsWith(".sh", StringComparison.OrdinalIgnoreCase) ||
// f.Name.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase));
// foreach (var projectFile in canReplaceFiles)
// {
// await ReplaceFileTextAsync(projectFile, "PackageName", packageName);
// await ReplaceFileTextAsync(projectFile, "CompanyName", companyName);
//
// await ReplaceFileTextAsync(projectFile, "DatabaseManagementName", dbm);
// }
// }
protected async virtual Task TryReplacePackageAndCompanyNameWithProjectFile(
List<FindFile> projectFiles,
string packageName,
string companyName,
DatabaseManagementSystem database = DatabaseManagementSystem.NotSpecified)
string dbm = "MySQL")
{
var canReplaceFiles = projectFiles.Where(f => !f.IsFolder && !f.Name.Contains("appsettings"));
foreach (var projectFile in canReplaceFiles)
{
await ReplaceFileTextAsync(projectFile, "PackageName", packageName);
await ReplaceFileTextAsync(projectFile, "CompanyName", companyName);
await ReplaceFileTextAsync(projectFile, "DatabaseManagementName", dbm);
}
}
protected virtual Task TryReplacePackageAndCompanyNameWithProjectFolder(
List<FindFile> projectFiles,
string packageName,
string companyName)
string companyName,
string dbm = "MySQL")
{
var canReplaceFiles = projectFiles
.OrderByDescending(f => f.Depth)
.OrderByDescending(f => !f.IsFolder);
foreach (var projectFile in canReplaceFiles)
{
var replaceFileName = projectFile.Name.Replace("PackageName", packageName).Replace("CompanyName", companyName);
var replaceFileName = projectFile.Name.Replace("PackageName", packageName).Replace("CompanyName", companyName).Replace("DatabaseManagementName", dbm);
if (File.Exists(projectFile.Name))
{
@ -238,7 +267,7 @@ namespace LINGYUN.Abp.Cli.Commands
}
var canReplacePaths = projectFiles
.Where(projectFile => projectFile.Name.Contains("PackageName") || projectFile.Name.Contains("CompanyName"))
.Where(projectFile => projectFile.Name.Contains("PackageName") || projectFile.Name.Contains("CompanyName") || projectFile.Name.Contains("DatabaseManagementName"))
.OrderByDescending(f => f.Depth)
.OrderByDescending(f => f.IsFolder);
foreach (var projectFile in canReplacePaths)

3
aspnet-core/framework/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json

@ -3,7 +3,8 @@
"LINGYUN.Abp.Cli": {
"commandName": "Project",
//"commandLineArgs": "generate-view -t vben-view -m auditing -o D:\\Projects\\Development\\view-script -url http://127.0.0.1:30000/"
"commandLineArgs": "generate-proxy -t flutter -asp rest-service -u http://127.0.0.1:30000 -m notifications -o D:\\Projects\\Development\\flutter-script -skip-cli-version-check"
// "commandLineArgs": "generate-proxy -t flutter -asp rest-service -u http://127.0.0.1:30000 -m notifications -o D:\\Projects\\Development\\flutter-script -skip-cli-version-check"
"commandLineArgs": "create MyCompanyName.MyProjectName -t lam -pk MyPackageName -o /Users/feijie/Projects/Tests --dbms MySql --cs \"Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None\" --no-random-port"
}
}
}

7
aspnet-core/framework/cli/LINGYUN.Abp.Cli/README.zh-Hans.md

@ -8,6 +8,13 @@
dotnet tool install --global LINGYUN.Abp.Cli
```
打包项目为LINGYUN.Abp.Cli.8.3.0.nupkg
```shell
dotnet pack -o ./nupkg
dotnet tool install -g LINGYUN.Abp.Cli --version 8.3.0 --add-source ./nupkg
```
## 使用方法
```shell

33
aspnet-core/framework/cloud-aliyun/README.md

@ -0,0 +1,33 @@
# LINGYUN.Abp.Aliyun 模块概述
## 简介
LINGYUN.Abp.Aliyun 模块集成了阿里云的 SDK,提供了对阿里云服务的全面支持,包括认证、短信服务和对象存储等功能。
## 包含的项目列表
- **LINGYUN.Abp.Aliyun**
- **LINGYUN.Abp.Aliyun.Features**
- **LINGYUN.Abp.Aliyun.SettingManagement**
## 每个项目的主要功能概述
### LINGYUN.Abp.Aliyun
- 提供阿里云服务的基础 SDK 集成。
- 支持阿里云 RAM 认证和 STS Token 访问。
- 支持短信服务和对象存储。
- 提供分布式缓存支持。
### LINGYUN.Abp.Aliyun.Features
- 提供阿里云服务的功能定义和管理。
- 支持启用/禁用阿里云服务功能。
- 与 ABP 功能管理系统集成。
### LINGYUN.Abp.Aliyun.SettingManagement
- 提供阿里云服务配置的查询接口。
- 通过 API 接口获取阿里云配置信息。
- 与 ABP 设置管理系统集成。
## 模块的整体用途和重要性
该模块为开发者提供了与阿里云服务的无缝集成,简化了云服务的使用和管理,提升了应用程序的灵活性和可扩展性。
## 如何使用或集成该模块
在项目中引用相应的模块,并根据需要配置阿里云的相关参数。确保与 ABP 框架的其他模块配合使用,以实现最佳效果。

42
aspnet-core/framework/cloud-tencent/README.md

@ -0,0 +1,42 @@
# LINGYUN.Abp.Tencent 模块概述
## 简介
LINGYUN.Abp.Tencent 模块集成了腾讯云的各项服务,提供了对腾讯云服务的全面支持,包括对象存储、短信服务、QQ 互联和语音合成等功能。
## 包含的项目列表
- **LINGYUN.Abp.Tencent**
- **LINGYUN.Abp.BlobStoring.Tencent**
- **LINGYUN.Abp.Sms.Tencent**
- **LINGYUN.Abp.Tencent.QQ**
- **LINGYUN.Abp.Tencent.SettingManagement**
- **LINGYUN.Abp.Tencent.TTS**
## 每个项目的主要功能概述
### LINGYUN.Abp.Tencent
- 提供腾讯云 SDK 客户端工厂,支持动态创建腾讯云各项服务的客户端。
- 支持多租户配置和多语言本地化。
- 提供统一的腾讯云服务配置管理。
### LINGYUN.Abp.BlobStoring.Tencent
- 支持腾讯云对象存储服务,自动创建存储桶。
- 支持多区域配置和文件大小限制。
### LINGYUN.Abp.Sms.Tencent
- 支持腾讯云短信服务的发送功能,支持多手机号批量发送。
- 内置错误处理和日志记录。
### LINGYUN.Abp.Tencent.QQ
- 支持 QQ 互联快速登录,支持多租户配置。
### LINGYUN.Abp.Tencent.SettingManagement
- 提供腾讯云服务的配置管理界面,支持全局和租户级别的配置管理。
### LINGYUN.Abp.Tencent.TTS
- 支持腾讯云语音合成服务,提供 TTS 客户端工厂。
## 模块的整体用途和重要性
该模块为开发者提供了与腾讯云服务的无缝集成,简化了云服务的使用和管理,提升了应用程序的灵活性和可扩展性。
## 如何使用或集成该模块
在项目中引用相应的模块,并根据需要配置腾讯云的相关参数。确保与 ABP 框架的其他模块配合使用,以实现最佳效果。

59
aspnet-core/framework/common/README.md

@ -0,0 +1,59 @@
# common 模块概述
## 模块简介
`common`模块是ABP框架的基础模块,提供了一系列通用功能和服务,旨在支持各种应用程序的开发和扩展。该模块包含多个子模块,每个子模块实现了特定的功能,帮助开发者快速构建高效的应用程序。
## 包含的项目列表
1. **LINGYUN.Abp.Aliyun.Authorization**
- 提供阿里云基础认证功能,支持AppKeyId和AccessKeySecret的配置。
2. **LINGYUN.Abp.AspNetCore.HttpOverrides**
- 实现HTTP传输标头的重写,支持获取反向代理中的真实客户地址。
3. **LINGYUN.Abp.AspNetCore.Mvc.Client**
- 提供可配置的用户配置缓存时间,支持多租户接口。
4. **LINGYUN.Abp.BackgroundJobs.Hangfire**
- 基于Hangfire实现的后台作业模块,支持即时、延迟和周期性任务。
5. **LINGYUN.Abp.ExceptionHandling**
- 提供统一的异常处理和通知机制,支持自定义异常处理程序。
6. **LINGYUN.Abp.Location**
- 提供地理编码、反向地理编码和IP地理位置解析功能。
7. **LINGYUN.Abp.IdGenerator**
- 实现分布式唯一ID生成器,支持雪花算法。
8. **LINGYUN.Abp.Wrapper**
- 统一包装API返回结果和异常处理。
## 每个项目的主要功能概述
- **阿里云认证模块**: 提供阿里云的认证功能,简化了对阿里云服务的访问。
- **HTTP重写模块**: 处理HTTP请求中的标头,确保获取真实的客户端地址。
- **MVC客户端模块**: 提供用户配置缓存,支持多租户架构。
- **后台作业模块**: 支持任务的调度和执行,确保后台任务的可靠性。
- **异常处理模块**: 处理应用中的异常,提供统一的通知机制。
- **位置服务模块**: 提供地理位置相关的功能,支持地址与坐标之间的转换。
- **ID生成模块**: 生成分布式唯一ID,确保在高并发环境下的唯一性。
- **包装器模块**: 统一处理API的返回结果和异常,提升API的可用性。
## 模块的整体用途和重要性
`common`模块为ABP框架提供了基础设施,支持开发者在构建应用时快速集成常用功能,减少重复工作,提高开发效率。通过这些模块,开发者能够更专注于业务逻辑的实现,而无需担心底层的实现细节。
## 如何使用或集成该模块的简要说明
在项目中使用`common`模块时,只需在模块类中添加相应的依赖项,并在`ConfigureServices`方法中进行必要的配置。例如:
```csharp
[DependsOn(typeof(LINGYUN.Abp.Aliyun.Authorization))]
public class YourProjectModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// 配置服务
}
}
```
## 提示
本项目中的README是由AI模型分析代码逻辑后自动生成的,如有误,请提issues或PR。

5
aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj

@ -35,6 +35,10 @@
<Content Include="appsettings.PostgreSql.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Remove="appsettings.json" />
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
@ -46,6 +50,7 @@
<ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin\LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj" />
<ProjectReference Include="..\LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql\LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql.csproj" />
<ProjectReference Include="..\LY.MicroService.Applications.Single.EntityFrameworkCore.MySql\LY.MicroService.Applications.Single.EntityFrameworkCore.Mysql.csproj" />
<ProjectReference Include="..\LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer\LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj" />
</ItemGroup>
</Project>

6
aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/SingleDbMigratorModule.cs

@ -1,7 +1,7 @@
using LINGYUN.Abp.UI.Navigation.VueVbenAdmin;
using Microsoft.Extensions.DependencyInjection;
using LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql;
// using LY.MicroService.Applications.Single.EntityFrameworkCore.MySql;
using LY.MicroService.Applications.Single.EntityFrameworkCore.MySql;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
@ -9,8 +9,8 @@ namespace LY.MicroService.Applications.Single.DbMigrator;
[DependsOn(
typeof(AbpUINavigationVueVbenAdminModule),
typeof(SingleMigrationsEntityFrameworkCorePostgreSqlModule),
// typeof(SingleMigrationsEntityFrameworkCoreMySqlModule),
// typeof(SingleMigrationsEntityFrameworkCorePostgreSqlModule),
typeof(SingleMigrationsEntityFrameworkCoreMySqlModule),
typeof(AbpAutofacModule)
)]
public partial class SingleDbMigratorModule : AbpModule

228
aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.SqlServer.json

@ -0,0 +1,228 @@
{
"App": {
"ShowPii": true,
"SelfUrl": "http://127.0.0.1:30001/",
"CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001",
"Urls": {
"Applications": {
"MVC": {
"RootUrl": "http://127.0.0.1:30001/",
"Urls": {
"Abp.Account.EmailConfirm": "Account/EmailConfirm",
"Abp.Account.EmailVerifyLogin": "Account/VerifyCode"
}
},
"STS": {
"RootUrl": "http://127.0.0.1:30001/"
},
"VueVbenAdmin": {
"RootUrl": "http://127.0.0.1:3100",
"Urls": {
"Abp.Account.EmailConfirm": "account/email-confirm"
}
}
}
}
},
"Auditing": {
"AllEntitiesSelector": true
},
"DistributedCache": {
"HideErrors": true,
"KeyPrefix": "LINGYUN.Abp.Application",
"GlobalCacheEntryOptions": {
"SlidingExpiration": "30:00:00",
"AbsoluteExpirationRelativeToNow": "60:00:00"
}
},
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=True"
},
"DistributedLock": {
"IsEnabled": true,
"Redis": {
"Configuration": "127.0.0.1,defaultDatabase=14"
}
},
"Elsa": {
"Features": {
"DefaultPersistence": {
"Enabled": true,
"ConnectionStringIdentifier": "Default",
"EntityFrameworkCore": {
"SqlServer": {
"Enabled": true
}
}
},
"Console": true,
"Http": true,
"Email": true,
"TemporalQuartz": true,
"JavaScriptActivities": true,
"UserTask": true,
"Conductor": true,
"Telnyx": true,
"BlobStoring": true,
"Emailing": true,
"Notification": true,
"Sms": true,
"IM": true,
"PublishWebhook": true,
"Webhooks": {
"Enabled": true,
"ConnectionStringIdentifier": "Default",
"EntityFrameworkCore": {
"SqlServer": {
"Enabled": true
}
}
},
"WorkflowSettings": {
"Enabled": true,
"ConnectionStringIdentifier": "Default",
"EntityFrameworkCore": {
"SqlServer": {
"Enabled": true
}
}
}
},
"Server": {
"BaseUrl": "http://127.0.0.1:30000"
}
},
"Quartz": {
"UsePersistentStore": false,
"Properties": {
"quartz.jobStore.dataSource": "tkm",
"quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
"quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz",
"quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;",
"quartz.dataSource.tkm.provider": "SqlServer",
"quartz.jobStore.clustered": "true",
"quartz.serializer.type": "json",
"quartz.dataSource.tkm.connectionStringName": "TaskManagement"
}
},
"Redis": {
"IsEnabled": true,
"Configuration": "127.0.0.1,defaultDatabase=15",
"InstanceName": "LINGYUN.Abp.Application"
},
"AuthServer": {
"UseOpenIddict": true,
"Authority": "http://127.0.0.1:30001/",
"ApiName": "lingyun-abp-application",
"SwaggerClientId": "InternalServiceClient",
"SwaggerClientSecret": "1q2w3E*"
},
"IdentityServer": {
"Clients": {
"VueAdmin": {
"ClientId": "vue-admin-client",
"RootUrl": "http://127.0.0.1:3100/"
},
"InternalService": {
"ClientId": "InternalServiceClient"
}
}
},
"OpenIddict": {
"Applications": {
"VueAdmin": {
"ClientId": "vue-admin-client",
"RootUrl": "http://127.0.0.1:3100/"
},
"InternalService": {
"ClientId": "InternalServiceClient"
}
},
"Lifetime": {
"AuthorizationCode": "00:05:00",
"AccessToken": "14:00:00",
"DeviceCode": "00:10:00",
"IdentityToken": "00:20:00",
"RefreshToken": "14:00:00",
"RefreshTokenReuseLeeway": "00:00:30",
"UserCode": "00:10:00"
}
},
"Identity": {
"Password": {
"RequiredLength": 6,
"RequiredUniqueChars": 0,
"RequireNonAlphanumeric": false,
"RequireLowercase": false,
"RequireUppercase": false,
"RequireDigit": false
},
"Lockout": {
"AllowedForNewUsers": false,
"LockoutDuration": 5,
"MaxFailedAccessAttempts": 5
},
"SignIn": {
"RequireConfirmedEmail": false,
"RequireConfirmedPhoneNumber": false
}
},
"FeatureManagement": {
"IsDynamicStoreEnabled": true
},
"SettingManagement": {
"IsDynamicStoreEnabled": true
},
"PermissionManagement": {
"IsDynamicStoreEnabled": true
},
"TextTemplating": {
"IsDynamicStoreEnabled": true
},
"WebhooksManagement": {
"IsDynamicStoreEnabled": true
},
"Logging": {
"Serilog": {
"Elasticsearch": {
"IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}"
}
}
},
"AuditLogging": {
"Elasticsearch": {
"IndexPrefix": "abp.dev.auditing"
}
},
"Elasticsearch": {
"NodeUris": "http://127.0.0.1:9200"
},
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"DotNetCore": "Debug"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Debug",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "Elasticsearch",
"Args": {
"nodeUris": "http://127.0.0.1:9200",
"indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}",
"autoRegisterTemplate": true,
"autoRegisterTemplateVersion": "ESv7"
}
}
]
}
}

3
aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json

@ -3,7 +3,8 @@
"Kind": "Local"
},
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"
"Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//MySql
// "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer"//PostgreSql
},
"StringEncryption": {
"DefaultPassPhrase": "s46c5q55nxpeS8Ra",

5828
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.Designer.cs

File diff suppressed because it is too large

183
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.cs

@ -0,0 +1,183 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migrations
{
/// <inheritdoc />
public partial class AddNewMigration_20241218_225542 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AbpAuthEntitites",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
DisplayName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
TypeFullName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsAuditEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthEntitites", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpAuthEntityProperties",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
DisplayName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
TypeFullName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ValueRange = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
TypeInfoId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthEntityProperties", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthEntityProperties_AbpAuthEntitites_TypeInfoId",
column: x => x.TypeInfoId,
principalTable: "AbpAuthEntitites",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpAuthOrganizationUnitEntityRules",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrgId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrgCode = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
Operation = table.Column<int>(type: "int", nullable: false),
FilterGroup = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EntityTypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
EntityTypeFullName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
AllowProperties = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthOrganizationUnitEntityRules", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthOrganizationUnitEntityRules_AbpAuthEntitites_EntityTy~",
column: x => x.EntityTypeId,
principalTable: "AbpAuthEntitites",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpAuthRoleEntityRules",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
RoleId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
RoleName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
Operation = table.Column<int>(type: "int", nullable: false),
FilterGroup = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EntityTypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
EntityTypeFullName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
AllowProperties = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthRoleEntityRules", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthRoleEntityRules_AbpAuthEntitites_EntityTypeId",
column: x => x.EntityTypeId,
principalTable: "AbpAuthEntitites",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthEntitites_TypeFullName",
table: "AbpAuthEntitites",
column: "TypeFullName");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthEntityProperties_TypeInfoId_TypeFullName",
table: "AbpAuthEntityProperties",
columns: new[] { "TypeInfoId", "TypeFullName" });
migrationBuilder.CreateIndex(
name: "IX_AbpAuthOrganizationUnitEntityRules_EntityTypeId",
table: "AbpAuthOrganizationUnitEntityRules",
column: "EntityTypeId");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthRoleEntityRules_EntityTypeId",
table: "AbpAuthRoleEntityRules",
column: "EntityTypeId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpAuthEntityProperties");
migrationBuilder.DropTable(
name: "AbpAuthOrganizationUnitEntityRules");
migrationBuilder.DropTable(
name: "AbpAuthRoleEntityRules");
migrationBuilder.DropTable(
name: "AbpAuthEntitites");
}
}
}

289
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs

@ -24,6 +24,257 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migratio
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.Property<Guid>("TypeInfoId")
.HasColumnType("char(36)");
b.Property<string>("ValueRange")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("ValueRange");
b.HasKey("Id");
b.HasIndex("TypeInfoId", "TypeFullName");
b.ToTable("AbpAuthEntityProperties", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAuditEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.HasKey("Id");
b.HasIndex("TypeFullName");
b.ToTable("AbpAuthEntitites", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowProperties")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("AllowProperties");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<string>("OrgCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("OrgCode");
b.Property<Guid>("OrgId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthOrganizationUnitEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowProperties")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("AllowProperties");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<Guid>("RoleId")
.HasColumnType("char(36)");
b.Property<string>("RoleName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("RoleName");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthRoleEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Demo.Authors.Author", b =>
{
b.Property<Guid>("Id")
@ -5254,6 +5505,39 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migratio
b.ToTable("AbpSettingDefinitions", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "TypeInfo")
.WithMany("Properties")
.HasForeignKey("TypeInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.Demo.Books.Book", b =>
{
b.HasOne("LINGYUN.Abp.Demo.Authors.Author", null)
@ -5616,6 +5900,11 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migratio
.HasForeignKey("AuthorizationId");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Navigation("Properties");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.Navigation("ConnectionStrings");

16
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer\LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer.csproj" />
<ProjectReference Include="..\LY.MicroService.Applications.Single.EntityFrameworkCore\LY.MicroService.Applications.Single.EntityFrameworkCore.csproj" />
</ItemGroup>
</Project>

59
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.en.md

@ -0,0 +1,59 @@
# SQL Server Database Migration Guide
This guide will help you manage SQL Server database migrations using the migration scripts.
## Prerequisites
1. Ensure .NET Core SDK is installed
2. Ensure Entity Framework Core tools are installed
```powershell
dotnet tool install --global dotnet-ef
```
3. Ensure SQL Server connection string is properly configured
## Usage Instructions
### 1. Create New Migration
1. Run the migration script in the `aspnet-core/migrations` directory:
```powershell
# Use English version
.\MigrateEn.ps1
# Or use Chinese version
.\Migrate.ps1
```
2. Select SQL Server database context from the menu:
```
[3] LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer
```
3. Enter migration name (optional):
- Press Enter to use default name: `AddNewMigration_yyyyMMdd_HHmmss`
- Or enter custom name, e.g.: `AddNewFeature`
### 2. Generate SQL Script
After creating the migration, the script will ask if you want to generate SQL script:
1. Choose whether to generate SQL script (Y/N)
2. If Y is selected, following options will be available:
- `[A]` - Generate SQL script for all migrations
- `[L]` - Generate SQL script for latest migration only
- `[0-9]` - Generate from specified migration version
Generated SQL scripts will be saved in:
```
aspnet-core/InitSql/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/
```
### 3. Apply Migration
Generated SQL scripts can be applied to database through:
1. Using SQL Server Management Studio or other SQL Server client tools to execute SQL script
2. Or using command line:
```bash
sqlcmd -S your_server -d your_database -i your_script.sql
```

59
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.md

@ -0,0 +1,59 @@
# SQL Server 数据库迁移指南
本指南将帮助您使用迁移脚本来管理 SQL Server 数据库的迁移操作。
## 前置条件
1. 确保已安装 .NET Core SDK
2. 确保已安装 Entity Framework Core 工具
```powershell
dotnet tool install --global dotnet-ef
```
3. 确保已正确配置 SQL Server 连接字符串
## 使用说明
### 1. 创建新的迁移
1. 在 `aspnet-core/migrations` 目录下运行迁移脚本:
```powershell
# 使用中文版本
.\Migrate.ps1
# 或使用英文版本
.\MigrateEn.ps1
```
2. 在菜单中选择 SQL Server 数据库上下文:
```
[3] LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer
```
3. 输入迁移名称(可选):
- 直接回车将使用默认名称:`AddNewMigration_yyyyMMdd_HHmmss`
- 或输入自定义名称,如:`AddNewFeature`
### 2. 生成 SQL 脚本
在创建迁移后,脚本会询问是否需要生成 SQL 脚本:
1. 选择是否生成 SQL 脚本 (Y/N)
2. 如果选择 Y,将提供以下选项:
- `[A]` - 生成所有迁移的 SQL 脚本
- `[L]` - 仅生成最新迁移的 SQL 脚本
- `[0-9]` - 从指定的迁移版本开始生成
生成的 SQL 脚本将保存在:
```
aspnet-core/InitSql/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/
```
### 3. 应用迁移
生成的 SQL 脚本可以通过以下方式应用到数据库:
1. 使用 SQL Server Management Studio 或其他 SQL Server 客户端工具执行 SQL 脚本
2. 或使用命令行:
```bash
sqlcmd -S your_server -d your_database -i your_script.sql
```

35
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsDbContextFactory.cs

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer;
public class SingleMigrationsDbContextFactory : IDesignTimeDbContextFactory<SingleMigrationsDbContext>
{
public SingleMigrationsDbContext CreateDbContext(string[] args)
{
var configuration = BuildConfiguration();
var connectionString = configuration.GetConnectionString("Default");
var builder = new DbContextOptionsBuilder<SingleMigrationsDbContext>()
.UseSqlServer(connectionString,
b => b.MigrationsAssembly("LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer"));
return new SingleMigrationsDbContext(builder!.Options);
}
private static IConfigurationRoot BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(),
"../LY.MicroService.Applications.Single.DbMigrator/"))
.AddJsonFile("appsettings.json", optional: false)
.AddJsonFile(
"appsettings.SqlServer.json",
optional: false);
return builder.Build();
}
}

26
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsEntityFrameworkCoreSqlServerModule.cs

@ -0,0 +1,26 @@
using LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer;
using Microsoft.Extensions.DependencyInjection;
using System;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.Modularity;
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer;
[DependsOn(
typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(AbpElsaEntityFrameworkCoreSqlServerModule),
typeof(SingleMigrationsEntityFrameworkCoreModule)
)]
public class SingleMigrationsEntityFrameworkCoreSqlServerModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<SingleMigrationsDbContext>();
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer();
});
}
}

200
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleDbMigrationService.cs

@ -1,101 +1,101 @@
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Migrations;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace LY.MicroService.Applications.Single.EntityFrameworkCore;
public class SingleDbMigrationService : EfCoreRuntimeDatabaseMigratorBase<SingleMigrationsDbContext>, ITransientDependency
{
protected IDataSeeder DataSeeder { get; }
protected ITenantRepository TenantRepository { get; }
public SingleDbMigrationService(
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IDataSeeder dataSeeder,
ITenantRepository tenantRepository)
: base("SingleDbMigrator", unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory)
{
DataSeeder = dataSeeder;
TenantRepository = tenantRepository;
}
protected async override Task LockAndApplyDatabaseMigrationsAsync()
{
await base.LockAndApplyDatabaseMigrationsAsync();
var tenants = await TenantRepository.GetListAsync();
foreach (var tenant in tenants.Where(x => x.IsActive))
{
Logger.LogInformation($"Trying to acquire the distributed lock for database migration: {DatabaseName} with tenant: {tenant.Name}.");
var schemaMigrated = false;
await using (var handle = await DistributedLock.TryAcquireAsync("DatabaseMigration_" + DatabaseName + "_Tenant" + tenant.Id.ToString()))
{
if (handle is null)
{
Logger.LogInformation($"Distributed lock could not be acquired for database migration: {DatabaseName} with tenant: {tenant.Name}. Operation cancelled.");
return;
}
Logger.LogInformation($"Distributed lock is acquired for database migration: {DatabaseName} with tenant: {tenant.Name}...");
using (CurrentTenant.Change(tenant.Id))
{
// Create database tables if needed
using var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false);
var dbContext = await ServiceProvider
.GetRequiredService<IDbContextProvider<SingleMigrationsDbContext>>()
.GetDbContextAsync();
var pendingMigrations = await dbContext
.Database
.GetPendingMigrationsAsync();
if (pendingMigrations.Any())
{
await dbContext.Database.MigrateAsync();
schemaMigrated = true;
}
await uow.CompleteAsync();
await SeedAsync();
if (schemaMigrated || AlwaysSeedTenantDatabases)
{
await DistributedEventBus.PublishAsync(
new AppliedDatabaseMigrationsEto
{
DatabaseName = DatabaseName,
TenantId = tenant.Id
}
);
}
}
}
Logger.LogInformation($"Distributed lock has been released for database migration: {DatabaseName} with tenant: {tenant.Name}...");
}
}
protected async override Task SeedAsync()
{
await DataSeeder.SeedAsync(CurrentTenant.Id);
}
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Migrations;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace LY.MicroService.Applications.Single.EntityFrameworkCore;
public class SingleDbMigrationService : EfCoreRuntimeDatabaseMigratorBase<SingleMigrationsDbContext>, ITransientDependency
{
protected IDataSeeder DataSeeder { get; }
protected ITenantRepository TenantRepository { get; }
public SingleDbMigrationService(
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IAbpDistributedLock abpDistributedLock,
IDistributedEventBus distributedEventBus,
ILoggerFactory loggerFactory,
IDataSeeder dataSeeder,
ITenantRepository tenantRepository)
: base("SingleDbMigrator", unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory)
{
DataSeeder = dataSeeder;
TenantRepository = tenantRepository;
}
protected async override Task LockAndApplyDatabaseMigrationsAsync()
{
await base.LockAndApplyDatabaseMigrationsAsync();
var tenants = await TenantRepository.GetListAsync();
foreach (var tenant in tenants.Where(x => x.IsActive))
{
Logger.LogInformation($"Trying to acquire the distributed lock for database migration: {DatabaseName} with tenant: {tenant.Name}.");
var schemaMigrated = false;
await using (var handle = await DistributedLock.TryAcquireAsync("DatabaseMigration_" + DatabaseName + "_Tenant" + tenant.Id.ToString()))
{
if (handle is null)
{
Logger.LogInformation($"Distributed lock could not be acquired for database migration: {DatabaseName} with tenant: {tenant.Name}. Operation cancelled.");
return;
}
Logger.LogInformation($"Distributed lock is acquired for database migration: {DatabaseName} with tenant: {tenant.Name}...");
using (CurrentTenant.Change(tenant.Id))
{
// Create database tables if needed
using var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false);
var dbContext = await ServiceProvider
.GetRequiredService<IDbContextProvider<SingleMigrationsDbContext>>()
.GetDbContextAsync();
var pendingMigrations = await dbContext
.Database
.GetPendingMigrationsAsync();
if (pendingMigrations.Any())
{
await dbContext.Database.MigrateAsync();
schemaMigrated = true;
}
await uow.CompleteAsync();
await SeedAsync();
if (schemaMigrated || AlwaysSeedTenantDatabases)
{
await DistributedEventBus.PublishAsync(
new AppliedDatabaseMigrationsEto
{
DatabaseName = DatabaseName,
TenantId = tenant.Id
}
);
}
}
}
Logger.LogInformation($"Distributed lock has been released for database migration: {DatabaseName} with tenant: {tenant.Name}...");
}
}
protected async override Task SeedAsync()
{
await DataSeeder.SeedAsync(CurrentTenant.Id);
}
}

5
aspnet-core/migrations/Migrate.ps1

@ -21,6 +21,11 @@ $dbContexts = @{
Context = "SingleMigrationsDbContext"
Factory = "SingleMigrationsDbContextFactory"
}
3 = @{
Name = "LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer"
Context = "SingleMigrationsDbContext"
Factory = "SingleMigrationsDbContextFactory"
}
}
# 显示DbContext选择菜单

5
aspnet-core/migrations/MigrateEn.ps1

@ -21,6 +21,11 @@ $dbContexts = @{
Context = "SingleMigrationsDbContext"
Factory = "SingleMigrationsDbContextFactory"
}
"3" = @{
Name = "LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer"
Context = "SingleMigrationsDbContext"
Factory = "SingleMigrationsDbContextFactory"
}
}
# Display DbContext selection menu

263
aspnet-core/services/Directory.Packages.props

@ -0,0 +1,263 @@
<Project>
<Import Project="..\..\Directory.Packages.props" />
<PropertyGroup>
<LYAbpPackageVersion>8.3.0</LYAbpPackageVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="DistributedLock.Redis" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Elsa.Activities.Email" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Elsa.Activities.Http" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Elsa.Activities.UserTask" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Elsa.Activities.Temporal.Quartz" Version="$(LYAbpPackageVersion)" />
<!--<PackageVersion Include="Elsa.Designer.Components.Web" Version="$(LYAbpPackageVersion)" />-->
<PackageVersion Include="Elsa.Webhooks.Api" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="OpenIddict.Validation.DataProtection" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="OpenIddict.Server.DataProtection" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.AspNetCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Enrichers.Environment" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Enrichers.Assembly" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Enrichers.Process" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Enrichers.Thread" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Sinks.Elasticsearch" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Serilog.Sinks.File" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Quartz.Serialization.Json" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Web.OpenIddict" Version="$(LYAbpPackageVersion)" />
<!--<PackageVersion Include="Volo.Abp.Account.Web.IdentityServer" Version="$(LYAbpPackageVersion)" />-->
<PackageVersion Include="Volo.Abp.AspNetCore.Serilog" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Autofac" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Caching.StackExchangeRedis" Version="$(LYAbpPackageVersion)" />
<!-- <PackageVersion Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="$(LYAbpPackageVersion)" />-->
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.IdentityServer" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.AspNetCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Imaging.ImageSharp" Version="$(LYAbpPackageVersion)" />
<!--<PackageVersion Include="Volo.Abp.IdentityServer.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />-->
<PackageVersion Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="LINGYUN.Abp.AuditLogging.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AuditLogging" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Authentication.QQ" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Authentication.WeChat" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Authorization.OrganizationUnits" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Aliyun.SettingManagement" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Aliyun" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent.QQ" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent.SettingManagement" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Tencent" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.HttpOverrides" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Data.DbMigrator" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Emailing" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis.Client" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Http.Client.Wrapper" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdGenerator" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.RealTime" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Wrapper" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Linq.Dynamic.Queryable" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Exporter.MiniExcel" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.Client" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Localization" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Localization.CultureMap" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Localization.Persistence" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Logging.Serilog.Elasticsearch" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Logging" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Serilog.Enrichers.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Serilog.Enrichers.UniqueId" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Sms.Aliyun" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.UI.Navigation" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenApi.Authorization" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MultiTenancy.Editions" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.WeChat" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.MiniProgram" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Handlers" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.SettingManagement" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Handlers" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat.Work" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WeChat" Version="$(LYAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="LINGYUN.Abp.Account.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.Templates" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Auditing.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Auditing.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Auditing.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.StackExchangeRedis" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Demo.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Demo.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Demo.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.BlobStoring" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Emailing" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.IM" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Notifications" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Sms" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Webhooks" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities" Version="$(LYAbpPackageVersion)" />
<!-- <PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql" Version="$(LYAbpPackageVersion)" />-->
<PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.PostgreSql" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Server" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Session" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.AspNetCore.Session" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Notifications" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.OrganizaztionUnits" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.LinkUser" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Portal" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.SmsValidator" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdentityServer.WeChat.Work" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Session.AspNetCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IM.SignalR" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IM" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MessageService.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Notifications" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Common" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Core" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Emailing" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.SignalR" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.Work" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.LinkUser" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Sms" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Portal" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat.Work" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.FileSystem" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Imaging" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.Minio" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OssManagement.SettingManagement" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Settings.VueVbenAdmin" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Platform.Theme.VueVbenAdmin" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Abstractions" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Activities" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.EventBus" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Jobs" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Notifications" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Quartz" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TaskManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Core" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.EventBus" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Identity" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Saas" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.HttpApi" Version="$(LYAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks" Version="$(LYAbpPackageVersion)" />
</ItemGroup>
</Project>

12
aspnet-core/services/LY.AIO.Applications.Single/.config/dotnet-tools.json

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "7.0.3",
"commands": [
"dotnet-ef"
]
}
}
}

2
aspnet-core/services/LY.AIO.Applications.Single/.gitignore

@ -0,0 +1,2 @@
wwwroot
package*.json

89
aspnet-core/services/LY.AIO.Applications.Single/Authentication/AbpCookieAuthenticationHandler.cs

@ -0,0 +1,89 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Options;
using System.Text.Encodings.Web;
namespace LY.AIO.Applications.Single.Authentication;
public class AbpCookieAuthenticationHandler : CookieAuthenticationHandler
{
public AbpCookieAuthenticationHandler(
IOptionsMonitor<CookieAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder) : base(options, logger, encoder)
{
}
public AbpCookieAuthenticationHandler(
IOptionsMonitor<CookieAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
{
}
protected const string XRequestFromHeader = "X-Request-From";
protected const string DontRedirectRequestFromHeader = "vben";
protected override Task InitializeEventsAsync()
{
var events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
},
OnRedirectToAccessDenied = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
},
OnRedirectToLogout = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
},
OnRedirectToReturnUrl = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
}
};
Events = events;
return Task.CompletedTask;
}
}

38
aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJob.cs

@ -0,0 +1,38 @@
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
namespace LY.AIO.Applications.Single.BackgroundJobs;
public class NotificationPublishJob : AsyncBackgroundJob<NotificationPublishJobArgs>, ITransientDependency
{
protected AbpNotificationsPublishOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected INotificationDataSerializer NotificationDataSerializer { get; }
public NotificationPublishJob(
IOptions<AbpNotificationsPublishOptions> options,
IServiceScopeFactory serviceScopeFactory,
INotificationDataSerializer notificationDataSerializer)
{
Options = options.Value;
ServiceScopeFactory = serviceScopeFactory;
NotificationDataSerializer = notificationDataSerializer;
}
public override async Task ExecuteAsync(NotificationPublishJobArgs args)
{
var providerType = Type.GetType(args.ProviderType);
using (var scope = ServiceScopeFactory.CreateScope())
{
if (scope.ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider)
{
var store = scope.ServiceProvider.GetRequiredService<INotificationStore>();
var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId);
notification.Data = NotificationDataSerializer.Serialize(notification.Data);
await publishProvider.PublishAsync(notification, args.UserIdentifiers);
}
}
}
}

22
aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJobArgs.cs

@ -0,0 +1,22 @@
using LINGYUN.Abp.Notifications;
namespace LY.AIO.Applications.Single.BackgroundJobs;
public class NotificationPublishJobArgs
{
public Guid? TenantId { get; set; }
public long NotificationId { get; set; }
public string ProviderType { get; set; }
public List<UserIdentifier> UserIdentifiers { get; set; }
public NotificationPublishJobArgs()
{
UserIdentifiers = new List<UserIdentifier>();
}
public NotificationPublishJobArgs(long id, string providerType, List<UserIdentifier> userIdentifiers, Guid? tenantId = null)
{
NotificationId = id;
ProviderType = providerType;
UserIdentifiers = userIdentifiers;
TenantId = tenantId;
}
}

11
aspnet-core/services/LY.AIO.Applications.Single/Controllers/HomeController.cs

@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;
namespace LY.AIO.Applications.Single.Controllers;
public class HomeController : Controller
{
public IActionResult Index()
{
return Redirect("/swagger");
}
}

70
aspnet-core/services/LY.AIO.Applications.Single/Controllers/SettingMergeController.cs

@ -0,0 +1,70 @@
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace LY.AIO.Applications.Single.Controllers;
[ExposeServices(
typeof(SettingController),
typeof(SettingMergeController))]
public class SettingMergeController : SettingController
{
private readonly SettingManagementMergeOptions _mergeOptions;
public SettingMergeController(
ISettingAppService settingAppService,
ISettingTestAppService settingTestAppService,
IOptions<SettingManagementMergeOptions> mergeOptions)
: base(settingAppService, settingTestAppService)
{
_mergeOptions = mergeOptions.Value;
}
[HttpGet]
[Route("by-current-tenant")]
public async override Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
var result = new SettingGroupResult();
var markTypeMap = new List<Type>
{
typeof(SettingMergeController),
};
foreach (var serviceType in _mergeOptions.GlobalSettingProviders
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType))))
{
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IReadonlySettingAppService>();
var currentResult = await settingService.GetAllForCurrentTenantAsync();
foreach (var group in currentResult.Items)
{
result.AddGroup(group);
}
markTypeMap.Add(serviceType);
}
return result;
}
[HttpGet]
[Route("by-global")]
public async override Task<SettingGroupResult> GetAllForGlobalAsync()
{
var result = new SettingGroupResult();
var markTypeMap = new List<Type>
{
typeof(SettingMergeController),
};
foreach (var serviceType in _mergeOptions.GlobalSettingProviders
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType))))
{
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IReadonlySettingAppService>();
var currentResult = await settingService.GetAllForGlobalAsync();
foreach (var group in currentResult.Items)
{
result.AddGroup(group);
}
markTypeMap.Add(serviceType);
}
return result;
}
}

45
aspnet-core/services/LY.AIO.Applications.Single/Controllers/UserSettingMergeController.cs

@ -0,0 +1,45 @@
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace LY.AIO.Applications.Single.Controllers;
[ExposeServices(
typeof(UserSettingController),
typeof(UserSettingMergeController))]
public class UserSettingMergeController : UserSettingController
{
private readonly SettingManagementMergeOptions _mergeOptions;
public UserSettingMergeController(
IUserSettingAppService service,
IOptions<SettingManagementMergeOptions> mergeOptions)
: base(service)
{
_mergeOptions = mergeOptions.Value;
}
[HttpGet]
[Route("by-current-user")]
public async override Task<SettingGroupResult> GetAllForCurrentUserAsync()
{
var result = new SettingGroupResult();
var markTypeMap = new List<Type>
{
typeof(UserSettingMergeController),
};
foreach (var serviceType in _mergeOptions.UserSettingProviders
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType))))
{
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IUserSettingAppService>();
var currentResult = await settingService.GetAllForCurrentUserAsync();
foreach (var group in currentResult.Items)
{
result.AddGroup(group);
}
markTypeMap.Add(serviceType);
}
return result;
}
}

19
aspnet-core/services/LY.AIO.Applications.Single/Dockerfile

@ -0,0 +1,19 @@
FROM mcr.microsoft.com/dotnet/aspnet:8.0
LABEL maintainer="colin.in@foxmail.com"
WORKDIR /app
COPY . /app
#东8区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone
EXPOSE 80/tcp
VOLUME [ "./app/blobs" ]
VOLUME [ "./app/Logs" ]
VOLUME [ "./app/Modules" ]
RUN apt update
RUN apt install wget -y
ENTRYPOINT ["dotnet", "LY.MicroService.Applications.Single.dll"]

59
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/ChatMessageEventHandler.cs

@ -0,0 +1,59 @@
using LINGYUN.Abp.IM;
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.RealTime;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace LY.AIO.Applications.Single.EventBus.Distributed
{
public class ChatMessageEventHandler : IDistributedEventHandler<RealTimeEto<ChatMessage>>, ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<ChatMessageEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="AbpIMOptions"/>.
/// </summary>
protected AbpIMOptions Options { get; }
protected IMessageStore MessageStore { get; }
protected IMessageBlocker MessageBlocker { get; }
protected IMessageSenderProviderManager MessageSenderProviderManager { get; }
public ChatMessageEventHandler(
IOptions<AbpIMOptions> options,
IMessageStore messageStore,
IMessageBlocker messageBlocker,
IMessageSenderProviderManager messageSenderProviderManager)
{
Options = options.Value;
MessageStore = messageStore;
MessageBlocker = messageBlocker;
MessageSenderProviderManager = messageSenderProviderManager;
Logger = NullLogger<ChatMessageEventHandler>.Instance;
}
public async virtual Task HandleEventAsync(RealTimeEto<ChatMessage> eventData)
{
Logger.LogDebug($"Persistent chat message.");
var message = eventData.Data;
// 消息拦截
// 扩展敏感词汇过滤
await MessageBlocker.InterceptAsync(message);
await MessageStore.StoreMessageAsync(message);
// 发送消息
foreach (var provider in MessageSenderProviderManager.Providers)
{
Logger.LogDebug($"Sending message with provider {provider.Name}");
await provider.SendMessageAsync(message);
}
}
}
}

470
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/NotificationEventHandler.cs

@ -0,0 +1,470 @@
using LINGYUN.Abp.Notifications;
using LY.AIO.Applications.Single.BackgroundJobs;
using LY.AIO.Applications.Single.MultiTenancy;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System.Globalization;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Json;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TextTemplating;
using Volo.Abp.Uow;
namespace LY.AIO.Applications.Single.EventBus.Distributed
{
/// <summary>
/// 订阅通知发布事件,统一发布消息
/// </summary>
/// <remarks>
/// 作用在于SignalR客户端只会与一台服务器建立连接,
/// 只有启用了SignlR服务端的才能真正将消息发布到客户端
/// </remarks>
public class NotificationEventHandler :
IDistributedEventHandler<NotificationEto<NotificationData>>,
IDistributedEventHandler<NotificationEto<NotificationTemplate>>,
ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<NotificationEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="AbpNotificationsPublishOptions"/>.
/// </summary>
protected AbpNotificationsPublishOptions Options { get; }
/// <summary>
/// Reference to <see cref="ICurrentTenant"/>.
/// </summary>
protected ICurrentTenant CurrentTenant { get; }
/// <summary>
/// Reference to <see cref="ITenantConfigurationCache"/>.
/// </summary>
protected ITenantConfigurationCache TenantConfigurationCache { get; }
/// <summary>
/// Reference to <see cref="IJsonSerializer"/>.
/// </summary>
protected IJsonSerializer JsonSerializer { get; }
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
protected IBackgroundJobManager BackgroundJobManager { get; }
/// <summary>
/// Reference to <see cref="ITemplateRenderer"/>.
/// </summary>
protected ITemplateRenderer TemplateRenderer { get; }
/// <summary>
/// Reference to <see cref="INotificationStore"/>.
/// </summary>
protected INotificationStore NotificationStore { get; }
/// <summary>
/// Reference to <see cref="IStringLocalizerFactory"/>.
/// </summary>
protected IStringLocalizerFactory StringLocalizerFactory { get; }
/// <summary>
/// Reference to <see cref="INotificationDataSerializer"/>.
/// </summary>
protected INotificationDataSerializer NotificationDataSerializer { get; }
/// <summary>
/// Reference to <see cref="INotificationDefinitionManager"/>.
/// </summary>
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationSubscriptionManager"/>.
/// </summary>
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationPublishProviderManager"/>.
/// </summary>
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
/// <summary>
/// Initializes a new instance of the <see cref="NotificationEventHandler"/> class.
/// </summary>
public NotificationEventHandler(
ICurrentTenant currentTenant,
ITenantConfigurationCache tenantConfigurationCache,
IJsonSerializer jsonSerializer,
ITemplateRenderer templateRenderer,
IBackgroundJobManager backgroundJobManager,
IStringLocalizerFactory stringLocalizerFactory,
IOptions<AbpNotificationsPublishOptions> options,
INotificationStore notificationStore,
INotificationDataSerializer notificationDataSerializer,
INotificationDefinitionManager notificationDefinitionManager,
INotificationSubscriptionManager notificationSubscriptionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
Options = options.Value;
TenantConfigurationCache = tenantConfigurationCache;
CurrentTenant = currentTenant;
JsonSerializer = jsonSerializer;
TemplateRenderer = templateRenderer;
BackgroundJobManager = backgroundJobManager;
StringLocalizerFactory = stringLocalizerFactory;
NotificationStore = notificationStore;
NotificationDataSerializer = notificationDataSerializer;
NotificationDefinitionManager = notificationDefinitionManager;
NotificationSubscriptionManager = notificationSubscriptionManager;
NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger<NotificationEventHandler>.Instance;
}
[UnitOfWork]
public async virtual Task HandleEventAsync(NotificationEto<NotificationTemplate> eventData)
{
var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name);
if (notification == null)
{
return;
}
var culture = eventData.Data.Culture;
if (culture.IsNullOrWhiteSpace())
{
culture = CultureInfo.CurrentCulture.Name;
}
using (CultureHelper.Use(culture, culture))
{
if (notification.NotificationType == NotificationType.System)
{
using (CurrentTenant.Change(null))
{
await SendToTenantAsync(null, notification, eventData);
var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync();
foreach (var activeTenant in allActiveTenants)
{
await SendToTenantAsync(activeTenant.Id, notification, eventData);
}
}
}
else
{
await SendToTenantAsync(eventData.TenantId, notification, eventData);
}
}
}
[UnitOfWork]
public async virtual Task HandleEventAsync(NotificationEto<NotificationData> eventData)
{
var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name);
if (notification == null)
{
return;
}
if (notification.NotificationType == NotificationType.System)
{
using (CurrentTenant.Change(null))
{
await SendToTenantAsync(null, notification, eventData);
var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync();
foreach (var activeTenant in allActiveTenants)
{
await SendToTenantAsync(activeTenant.Id, notification, eventData);
}
}
}
else
{
await SendToTenantAsync(eventData.TenantId, notification, eventData);
}
}
protected async virtual Task SendToTenantAsync(
Guid? tenantId,
NotificationDefinition notification,
NotificationEto<NotificationTemplate> eventData)
{
using (CurrentTenant.Change(tenantId))
{
var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers);
// 过滤用户指定提供者
if (eventData.UseProviders.Any())
{
providers = providers.Where(p => eventData.UseProviders.Contains(p.Name));
}
else if (notification.Providers.Any())
{
providers = providers.Where(p => notification.Providers.Contains(p.Name));
}
var notificationInfo = new NotificationInfo
{
Name = notification.Name,
TenantId = tenantId,
Severity = eventData.Severity,
Type = notification.NotificationType,
ContentType = notification.ContentType,
CreationTime = eventData.CreationTime,
Lifetime = notification.NotificationLifetime,
};
notificationInfo.SetId(eventData.Id);
var title = notification.DisplayName.Localize(StringLocalizerFactory);
var message = "";
try
{
// 由于模板通知受租户影响, 格式化失败的消息将被丢弃.
message = await TemplateRenderer.RenderAsync(
templateName: eventData.Data.Name,
model: eventData.Data.ExtraProperties,
cultureName: eventData.Data.Culture,
globalContext: new Dictionary<string, object>
{
// 模板不支持 $ 字符, 改为普通关键字
{ NotificationKeywords.Name, notification.Name },
{ NotificationKeywords.FormUser, eventData.Data.FormUser },
{ NotificationKeywords.Id, eventData.Id },
{ NotificationKeywords.Title, title.ToString() },
{ NotificationKeywords.CreationTime, eventData.CreationTime.ToString(Options.DateTimeFormat) },
});
}
catch(Exception ex)
{
Logger.LogWarning("Formatting template notification failed, message will be discarded, cause :{message}", ex.Message);
return;
}
var notificationData = new NotificationData();
notificationData.WriteStandardData(
title: title.ToString(),
message: message,
createTime: eventData.CreationTime,
formUser: eventData.Data.FormUser);
notificationData.ExtraProperties.AddIfNotContains(eventData.Data.ExtraProperties);
notificationInfo.Data = notificationData;
var subscriptionUsers = await GerSubscriptionUsersAsync(
notificationInfo.Name,
eventData.Users,
tenantId);
await PersistentNotificationAsync(
notificationInfo,
subscriptionUsers,
providers);
if (subscriptionUsers.Any())
{
// 发布通知
foreach (var provider in providers)
{
await PublishToSubscriberAsync(provider, notificationInfo, subscriptionUsers);
}
}
}
}
protected async virtual Task SendToTenantAsync(
Guid? tenantId,
NotificationDefinition notification,
NotificationEto<NotificationData> eventData)
{
using (CurrentTenant.Change(tenantId))
{
var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers);
// 过滤用户指定提供者
if (eventData.UseProviders.Any())
{
providers = providers.Where(p => eventData.UseProviders.Contains(p.Name));
}
else if (notification.Providers.Any())
{
providers = providers.Where(p => notification.Providers.Contains(p.Name));
}
var notificationInfo = new NotificationInfo
{
Name = notification.Name,
CreationTime = eventData.CreationTime,
Data = eventData.Data,
Severity = eventData.Severity,
Lifetime = notification.NotificationLifetime,
TenantId = tenantId,
Type = notification.NotificationType,
ContentType = notification.ContentType,
};
notificationInfo.SetId(eventData.Id);
notificationInfo.Data = NotificationDataSerializer.Serialize(notificationInfo.Data);
// 获取用户订阅
var subscriptionUsers = await GerSubscriptionUsersAsync(
notificationInfo.Name,
eventData.Users,
tenantId);
// 持久化通知
await PersistentNotificationAsync(
notificationInfo,
subscriptionUsers,
providers);
if (subscriptionUsers.Any())
{
// 发布订阅通知
foreach (var provider in providers)
{
await PublishToSubscriberAsync(provider, notificationInfo, subscriptionUsers);
}
}
}
}
/// <summary>
/// 获取用户订阅列表
/// </summary>
/// <param name="notificationName">通知名称</param>
/// <param name="sendToUsers">接收用户列表</param>
/// <param name="tenantId">租户标识</param>
/// <returns>用户订阅列表</returns>
protected async Task<IEnumerable<UserIdentifier>> GerSubscriptionUsersAsync(
string notificationName,
IEnumerable<UserIdentifier> sendToUsers,
Guid? tenantId = null)
{
try
{
// 获取用户订阅列表
var userSubscriptions = await NotificationSubscriptionManager.GetUsersSubscriptionsAsync(
tenantId,
notificationName,
sendToUsers);
return userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName));
}
catch(Exception ex)
{
Logger.LogWarning("Failed to get user subscription, message will not be received by the user, reason: {message}", ex.Message);
}
return new List<UserIdentifier>();
}
/// <summary>
/// 持久化通知并返回订阅用户列表
/// </summary>
/// <param name="notificationInfo">通知实体</param>
/// <param name="subscriptionUsers">订阅用户列表</param>
/// <param name="sendToProviders">通知发送提供者</param>
/// <returns>返回订阅者列表</returns>
protected async Task PersistentNotificationAsync(
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUsers,
IEnumerable<INotificationPublishProvider> sendToProviders)
{
try
{
// 持久化通知
await NotificationStore.InsertNotificationAsync(notificationInfo);
if (!subscriptionUsers.Any())
{
return;
}
// 持久化用户通知
await NotificationStore.InsertUserNotificationsAsync(notificationInfo, subscriptionUsers.Select(u => u.UserId));
if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne)
{
// 一次性通知取消用户订阅
await NotificationStore.DeleteUserSubscriptionAsync(
notificationInfo.TenantId,
subscriptionUsers,
notificationInfo.Name);
}
}
catch (Exception ex)
{
Logger.LogWarning("Failed to persistent notification failed, reason: {message}", ex.Message);
foreach (var provider in sendToProviders)
{
// 处理持久化失败进入后台队列
await ProcessingFailedToQueueAsync(provider, notificationInfo, subscriptionUsers);
}
}
}
/// <summary>
/// 发布订阅者通知
/// </summary>
/// <param name="provider">通知发布者</param>
/// <param name="notificationInfo">通知信息</param>
/// <param name="subscriptionUserIdentifiers">订阅用户列表</param>
/// <returns></returns>
protected async Task PublishToSubscriberAsync(
INotificationPublishProvider provider,
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUsers)
{
try
{
Logger.LogDebug($"Sending notification with provider {provider.Name}");
// 2024-10-10: 框架层面应该取消通知数据转换,而是交给提供商来实现
//var notifacationDataMapping = Options.NotificationDataMappings
// .GetMapItemOrDefault(provider.Name, notificationInfo.Name);
//if (notifacationDataMapping != null)
//{
// notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
//}
// 发布
await provider.PublishAsync(notificationInfo, subscriptionUsers);
Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
}
catch (Exception ex)
{
Logger.LogWarning($"Send notification error with provider {provider.Name}");
Logger.LogWarning($"Error message:{ex.Message}");
Logger.LogDebug($"Failed to send notification {notificationInfo.Name}. Try to push notification to background job");
// 发送失败的消息进入后台队列
await ProcessingFailedToQueueAsync(provider, notificationInfo, subscriptionUsers);
}
}
/// <summary>
/// 处理失败的消息进入后台队列
/// </summary>
/// <remarks>
/// 注: 如果入队失败,消息将被丢弃.
/// </remarks>
/// <param name="provider"></param>
/// <param name="notificationInfo"></param>
/// <param name="subscriptionUsers"></param>
/// <returns></returns>
protected async Task ProcessingFailedToQueueAsync(
INotificationPublishProvider provider,
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUsers)
{
try
{
// 发送失败的消息进入后台队列
await BackgroundJobManager.EnqueueAsync(
new NotificationPublishJobArgs(
notificationInfo.GetId(),
provider.GetType().AssemblyQualifiedName,
subscriptionUsers.ToList(),
notificationInfo.TenantId));
}
catch(Exception ex)
{
Logger.LogWarning("Failed to push to background job, notification will be discarded, error cause: {message}", ex.Message);
}
}
}
}

53
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs

@ -0,0 +1,53 @@
using LINGYUN.Abp.Saas.Tenants;
using LY.AIO.Applications.Single.MultiTenancy;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace LY.AIO.Applications.Single.EventBus.Distributed
{
public class TenantSynchronizer :
IDistributedEventHandler<EntityCreatedEto<TenantEto>>,
IDistributedEventHandler<EntityUpdatedEto<TenantEto>>,
IDistributedEventHandler<EntityDeletedEto<TenantEto>>,
IDistributedEventHandler<TenantConnectionStringUpdatedEto>,
ITransientDependency
{
protected IDataSeeder DataSeeder { get; }
protected ITenantConfigurationCache TenantConfigurationCache { get; }
public TenantSynchronizer(
IDataSeeder dataSeeder,
ITenantConfigurationCache tenantConfigurationCache)
{
DataSeeder = dataSeeder;
TenantConfigurationCache = tenantConfigurationCache;
}
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEto<TenantEto> eventData)
{
await TenantConfigurationCache.RefreshAsync();
await DataSeeder.SeedAsync(eventData.Entity.Id);
}
public async virtual Task HandleEventAsync(EntityUpdatedEto<TenantEto> eventData)
{
await TenantConfigurationCache.RefreshAsync();
}
public async virtual Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData)
{
await TenantConfigurationCache.RefreshAsync();
}
public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData)
{
await TenantConfigurationCache.RefreshAsync();
}
}
}

30
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/UserCreateEventHandler.cs

@ -0,0 +1,30 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Users;
namespace LY.AIO.Applications.Single.EventBus.Distributed
{
public class UserCreateEventHandler : IDistributedEventHandler<EntityCreatedEto<UserEto>>, ITransientDependency
{
private readonly ILocalEventBus _localEventBus;
public UserCreateEventHandler(
ILocalEventBus localEventBus)
{
_localEventBus = localEventBus;
}
/// <summary>
/// 接收添加用户事件,发布本地事件
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
public async Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
var localUserCreateEventData = new EntityCreatedEventData<UserEto>(eventData.Entity);
await _localEventBus.PublishAsync(localUserCreateEventData);
}
}
}

112
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/WebhooksEventHandler.cs

@ -0,0 +1,112 @@
using LINGYUN.Abp.Webhooks;
using LINGYUN.Abp.Webhooks.EventBus;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
namespace LY.AIO.Applications.Single.EventBus.Distributed;
public class WebhooksEventHandler :
IDistributedEventHandler<WebhooksEventData>,
ITransientDependency
{
public IWebhookEventStore WebhookEventStore { get; set; }
private readonly ICurrentTenant _currentTenant;
private readonly IBackgroundJobManager _backgroundJobManager;
private readonly IWebhookSubscriptionManager _webhookSubscriptionManager;
public WebhooksEventHandler(
IWebhookSubscriptionManager webhookSubscriptionManager,
ICurrentTenant currentTenant,
IBackgroundJobManager backgroundJobManager)
{
_currentTenant = currentTenant;
_backgroundJobManager = backgroundJobManager;
_webhookSubscriptionManager = webhookSubscriptionManager;
WebhookEventStore = NullWebhookEventStore.Instance;
}
public async virtual Task HandleEventAsync(WebhooksEventData eventData)
{
var subscriptions = await _webhookSubscriptionManager
.GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync(
eventData.TenantIds,
eventData.WebhookName);
await PublishAsync(eventData.WebhookName, eventData.Data, subscriptions, eventData.SendExactSameData, eventData.Headers);
}
protected async virtual Task PublishAsync(
string webhookName,
string data,
List<WebhookSubscriptionInfo> webhookSubscriptions,
bool sendExactSameData = false,
WebhookHeader headers = null)
{
if (webhookSubscriptions.IsNullOrEmpty())
{
return;
}
var subscriptionsGroupedByTenant = webhookSubscriptions.GroupBy(x => x.TenantId);
foreach (var subscriptionGroupedByTenant in subscriptionsGroupedByTenant)
{
var webhookInfo = await SaveAndGetWebhookAsync(subscriptionGroupedByTenant.Key, webhookName, data);
foreach (var webhookSubscription in subscriptionGroupedByTenant)
{
var headersToSend = webhookSubscription.Headers;
if (headers != null)
{
if (headers.UseOnlyGivenHeaders)//do not use the headers defined in subscription
{
headersToSend = headers.Headers;
}
else
{
//use the headers defined in subscription. If additional headers has same header, use additional headers value.
foreach (var additionalHeader in headers.Headers)
{
headersToSend[additionalHeader.Key] = additionalHeader.Value;
}
}
}
await _backgroundJobManager.EnqueueAsync(new WebhookSenderArgs
{
TenantId = webhookSubscription.TenantId,
WebhookEventId = webhookInfo.Id,
Data = webhookInfo.Data,
WebhookName = webhookInfo.WebhookName,
WebhookSubscriptionId = webhookSubscription.Id,
Headers = headersToSend,
Secret = webhookSubscription.Secret,
WebhookUri = webhookSubscription.WebhookUri,
SendExactSameData = sendExactSameData
});
}
}
}
protected async virtual Task<WebhookEvent> SaveAndGetWebhookAsync(
Guid? tenantId,
string webhookName,
string data)
{
var webhookInfo = new WebhookEvent
{
WebhookName = webhookName,
Data = data,
TenantId = tenantId
};
var webhookId = await WebhookEventStore.InsertAndGetIdAsync(webhookInfo);
webhookInfo.Id = webhookId;
return webhookInfo;
}
}

58
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateJoinIMEventHandler.cs

@ -0,0 +1,58 @@
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace LY.AIO.Applications.Single.EventBus.Local
{
public class UserCreateJoinIMEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency
{
private readonly IChatDataSeeder _chatDataSeeder;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public UserCreateJoinIMEventHandler(
IChatDataSeeder chatDataSeeder,
INotificationSubscriptionManager notificationSubscriptionManager)
{
_chatDataSeeder = chatDataSeeder;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
/// <summary>
/// 接收添加用户事件,初始化IM用户种子
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData)
{
await SeedChatDataAsync(eventData.Entity);
await SeedUserSubscriptionNotifiersAsync(eventData.Entity);
}
protected async virtual Task SeedChatDataAsync(IUserData user)
{
await _chatDataSeeder.SeedAsync(user);
}
protected async virtual Task SeedUserSubscriptionNotifiersAsync(IUserData user)
{
var userIdentifier = new UserIdentifier(user.Id, user.UserName);
await _notificationSubscriptionManager
.SubscribeAsync(
user.TenantId,
userIdentifier,
MessageServiceNotificationNames.IM.FriendValidation);
await _notificationSubscriptionManager
.SubscribeAsync(
user.TenantId,
userIdentifier,
MessageServiceNotificationNames.IM.NewFriend);
}
}
}

69
aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateSendWelcomeEventHandler.cs

@ -0,0 +1,69 @@
using LINGYUN.Abp.Notifications;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Users;
namespace LY.AIO.Applications.Single.EventBus.Local
{
public class UserCreateSendWelcomeEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency
{
private readonly INotificationSender _notificationSender;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public UserCreateSendWelcomeEventHandler(
INotificationSender notificationSender,
INotificationSubscriptionManager notificationSubscriptionManager
)
{
_notificationSender = notificationSender;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
public async Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData)
{
var userIdentifer = new UserIdentifier(eventData.Entity.Id, eventData.Entity.UserName);
// 订阅用户欢迎消息
await SubscribeInternalNotifers(userIdentifer, eventData.Entity.TenantId);
await _notificationSender.SendNofiterAsync(
UserNotificationNames.WelcomeToApplication,
new NotificationTemplate(
UserNotificationNames.WelcomeToApplication,
formUser: eventData.Entity.UserName,
data: new Dictionary<string, object>
{
{ "name", eventData.Entity.UserName },
}),
userIdentifer,
eventData.Entity.TenantId,
NotificationSeverity.Info);
}
private async Task SubscribeInternalNotifers(UserIdentifier userIdentifer, Guid? tenantId = null)
{
// 订阅内置通知
await _notificationSubscriptionManager
.SubscribeAsync(
tenantId,
userIdentifer,
DefaultNotifications.SystemNotice);
await _notificationSubscriptionManager
.SubscribeAsync(
tenantId,
userIdentifer,
DefaultNotifications.OnsideNotice);
await _notificationSubscriptionManager
.SubscribeAsync(
tenantId,
userIdentifer,
DefaultNotifications.ActivityNotice);
// 订阅用户欢迎消息
await _notificationSubscriptionManager
.SubscribeAsync(
tenantId,
userIdentifer,
UserNotificationNames.WelcomeToApplication);
}
}
}

19
aspnet-core/services/LY.AIO.Applications.Single/IdentityResources/CustomIdentityResources.cs

@ -0,0 +1,19 @@
using LINGYUN.Abp.Identity;
using IdentityServer4.Models;
namespace LY.AIO.Applications.Single.IdentityResources;
public class CustomIdentityResources
{
public class AvatarUrl : IdentityResource
{
public AvatarUrl()
{
Name = IdentityConsts.ClaimType.Avatar.Name;
DisplayName = IdentityConsts.ClaimType.Avatar.DisplayName;
Description = IdentityConsts.ClaimType.Avatar.Description;
Emphasize = true;
UserClaims = new string[] { IdentityConsts.ClaimType.Avatar.Name };
}
}
}

272
aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj

@ -0,0 +1,272 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\..\common.secrets.props" />
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>LY.AIO.Applications.Single</RootNamespace>
</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="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="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" />
<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" />
</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" />
</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" />
</ItemGroup>
<ItemGroup>
<Folder Include="blobs\host\public\" />
</ItemGroup>
<ItemGroup>
<None Remove="blobs\host\public\iShot_2024-12-04_11.51.43.png" />
</ItemGroup>
</Project>

935
aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs

@ -0,0 +1,935 @@
using Elsa;
using Elsa.Options;
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;
using LINGYUN.Abp.Idempotent;
using LINGYUN.Abp.Identity.Session;
using LINGYUN.Abp.IdentityServer.IdentityResources;
using LINGYUN.Abp.Localization.CultureMap;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.OpenIddict.AspNetCore.Session;
using LINGYUN.Abp.OpenIddict.LinkUser;
using LINGYUN.Abp.OpenIddict.Permissions;
using LINGYUN.Abp.OpenIddict.Portal;
using LINGYUN.Abp.OpenIddict.Sms;
using LINGYUN.Abp.OpenIddict.WeChat;
using LINGYUN.Abp.Saas;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Tencent.Localization;
using LINGYUN.Abp.TextTemplating;
using LINGYUN.Abp.WebhooksManagement;
using LINGYUN.Abp.WeChat.Common.Messages.Handlers;
using LINGYUN.Abp.WeChat.Localization;
using LINGYUN.Abp.WeChat.Work;
using LINGYUN.Abp.Wrapper;
using LINGYUN.Platform.Localization;
using LY.AIO.Applications.Single.Authentication;
using LY.AIO.Applications.Single.IdentityResources;
using LY.AIO.Applications.Single.Microsoft.Extensions.DependencyInjection;
using LY.AIO.Applications.Single.WeChat.Official.Messages;
using Medallion.Threading;
using Medallion.Threading.Redis;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
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 Quartz;
using StackExchange.Redis;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.Auditing;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Caching;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Http.Client;
using Volo.Abp.Identity.Localization;
using Volo.Abp.IdentityServer;
using Volo.Abp.IdentityServer.Localization;
using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Localization;
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 VoloAbpExceptionHandlingOptions = Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingOptions;
namespace LY.AIO.Applications.Single;
public partial class MicroServiceApplicationsSingleModule
{
protected const string DefaultCorsPolicyName = "Default";
public static string ApplicationName { get; set; } = "MicroService-Applications-Single";
private readonly static OneTimeRunner OneTimeRunner = new();
private void PreConfigureFeature()
{
OneTimeRunner.Run(() =>
{
GlobalFeatureManager.Instance.Modules.Editions().EnableAll();
});
}
private void PreConfigureApp(IConfiguration configuration)
{
AbpSerilogEnrichersConsts.ApplicationName = ApplicationName;
PreConfigure<AbpSerilogEnrichersUniqueIdOptions>(options =>
{
// 以开放端口区别,应在0-31之间
options.SnowflakeIdOptions.WorkerId = 1;
options.SnowflakeIdOptions.WorkerIdBits = 5;
options.SnowflakeIdOptions.DatacenterId = 1;
});
if (configuration.GetValue<bool>("App:ShowPii"))
{
IdentityModelEventSource.ShowPII = true;
}
}
private void PreConfigureAuthServer(IConfiguration configuration)
{
PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddValidation(options =>
{
//options.AddAudiences("lingyun-abp-application");
options.UseLocalServer();
options.UseAspNetCore();
options.UseDataProtection();
});
});
}
private void PreConfigureIdentity()
{
PreConfigure<IdentityBuilder>(builder =>
{
builder.AddDefaultTokenProviders();
});
}
private void PreConfigureCertificate(IConfiguration configuration, IWebHostEnvironment environment)
{
var cerConfig = configuration.GetSection("Certificates");
if (environment.IsProduction() && cerConfig.Exists())
{
// 开发环境下存在证书配置
// 且证书文件存在则使用自定义的证书文件来启动Ids服务器
var cerPath = Path.Combine(environment.ContentRootPath, cerConfig["CerPath"]);
if (File.Exists(cerPath))
{
var certificate = new X509Certificate2(cerPath, cerConfig["Password"]);
if (configuration.GetValue<bool>("AuthServer:UseOpenIddict"))
{
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.AddSigningCertificate(certificate);
builder.AddEncryptionCertificate(certificate);
builder.UseDataProtection();
// 禁用https
builder.UseAspNetCore()
.DisableTransportSecurityRequirement();
});
}
else
{
PreConfigure<AbpIdentityServerBuilderOptions>(options =>
{
options.AddDeveloperSigningCredential = false;
});
PreConfigure<IIdentityServerBuilder>(builder =>
{
builder.AddSigningCredential(certificate);
});
}
}
}
else
{
if (configuration.GetValue<bool>("AuthServer:UseOpenIddict"))
{
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
PreConfigure<OpenIddictServerBuilder>(builder =>
{
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
using (var algorithm = RSA.Create(keySizeInBits: 2048))
{
var subject = new X500DistinguishedName("CN=Fabrikam Encryption Certificate");
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true));
var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2));
builder.AddSigningCertificate(certificate);
}
using (var algorithm = RSA.Create(keySizeInBits: 2048))
{
var subject = new X500DistinguishedName("CN=Fabrikam Signing Certificate");
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true));
var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2));
builder.AddEncryptionCertificate(certificate);
}
builder.UseDataProtection();
// 禁用https
builder.UseAspNetCore()
.DisableTransportSecurityRequirement();
});
}
}
}
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");
var startups = new[]
{
typeof(Elsa.Activities.Console.Startup),
typeof(Elsa.Activities.Http.Startup),
typeof(Elsa.Activities.UserTask.Startup),
typeof(Elsa.Activities.Temporal.Quartz.Startup),
typeof(Elsa.Activities.Email.Startup),
typeof(Elsa.Scripting.JavaScript.Startup),
typeof(Elsa.Activities.Webhooks.Startup),
};
PreConfigure<ElsaOptionsBuilder>(elsa =>
{
elsa
.AddActivitiesFrom<MicroServiceApplicationsSingleModule>()
.AddWorkflowsFrom<MicroServiceApplicationsSingleModule>()
.AddFeatures(startups, configuration)
.ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options));
elsa.DistributedLockingOptionsBuilder
.UseProviderFactory(sp => name =>
{
var provider = sp.GetRequiredService<IDistributedLockProvider>();
return provider.CreateLock(name);
});
});
services.AddNotificationHandlersFrom<MicroServiceApplicationsSingleModule>();
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(Elsa.Webhooks.Api.Endpoints.List).Assembly);
});
}
private void ConfigureAuthServer(IConfiguration configuration)
{
Configure<OpenIddictServerAspNetCoreBuilder>(builder =>
{
builder.DisableTransportSecurityRequirement();
});
Configure<OpenIddictServerAspNetCoreOptions>(options =>
{
options.DisableTransportSecurityRequirement = true;
});
Configure<OpenIddictServerOptions>(options =>
{
var lifetime = configuration.GetSection("OpenIddict:Lifetime");
options.AuthorizationCodeLifetime = lifetime.GetValue("AuthorizationCode", options.AuthorizationCodeLifetime);
options.AccessTokenLifetime = lifetime.GetValue("AccessToken", options.AccessTokenLifetime);
options.DeviceCodeLifetime = lifetime.GetValue("DeviceCode", options.DeviceCodeLifetime);
options.IdentityTokenLifetime = lifetime.GetValue("IdentityToken", options.IdentityTokenLifetime);
options.RefreshTokenLifetime = lifetime.GetValue("RefreshToken", options.RefreshTokenLifetime);
options.RefreshTokenReuseLeeway = lifetime.GetValue("RefreshTokenReuseLeeway", options.RefreshTokenReuseLeeway);
options.UserCodeLifetime = lifetime.GetValue("UserCode", options.UserCodeLifetime);
});
Configure<AbpOpenIddictAspNetCoreSessionOptions>(options =>
{
options.PersistentSessionGrantTypes.Add(SmsTokenExtensionGrantConsts.GrantType);
options.PersistentSessionGrantTypes.Add(PortalTokenExtensionGrantConsts.GrantType);
options.PersistentSessionGrantTypes.Add(LinkUserTokenExtensionGrantConsts.GrantType);
options.PersistentSessionGrantTypes.Add(WeChatTokenExtensionGrantConsts.OfficialGrantType);
options.PersistentSessionGrantTypes.Add(WeChatTokenExtensionGrantConsts.MiniProgramGrantType);
options.PersistentSessionGrantTypes.Add(AbpWeChatWorkGlobalConsts.GrantType);
});
}
private void ConfigureEndpoints(IServiceCollection services)
{
// 不需要
//Configure<AbpEndpointRouterOptions>(options =>
//{
// options.EndpointConfigureActions.Add(
// (context) =>
// {
// context.Endpoints.MapFallbackToPage("/_Host");
// });
//});
var preActions = services.GetPreConfigureActions<AbpAspNetCoreMvcOptions>();
services.AddAbpApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
//options.ApiVersionReader = new HeaderApiVersionReader("api-version"); //Supports header too
//options.ApiVersionReader = new MediaTypeApiVersionReader(); //Supports accept header too
}, mvcOptions =>
{
mvcOptions.ConfigureAbp(preActions.Configure());
});
//services.AddApiVersioning(config =>
//{
// // Specify the default API Version as 1.0
// config.DefaultApiVersion = new ApiVersion(1, 0);
// // Advertise the API versions supported for the particular endpoint (through 'api-supported-versions' response header which lists all available API versions for that endpoint)
// config.ReportApiVersions = true;
//});
//services.AddVersionedApiExplorer(options =>
//{
// // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// // note: the specified format code will format the version as "'v'major[.minor][-status]"
// options.GroupNameFormat = "'v'VVV";
// // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// // can also be used to control the format of the API version in route templates
// options.SubstituteApiVersionInUrl = true;
//});
}
private void ConfigureKestrelServer()
{
Configure<KestrelServerOptions>(options =>
{
options.Limits.MaxRequestBodySize = null;
options.Limits.MaxRequestBufferSize = null;
});
}
private void ConfigureBlobStoring(IConfiguration configuration)
{
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureAll((containerName, containerConfiguration) =>
{
containerConfiguration.UseFileSystem(fileSystem =>
{
fileSystem.BasePath = Path.Combine(Directory.GetCurrentDirectory(), "blobs");
});
//containerConfiguration.UseMinio(minio =>
//{
// configuration.GetSection("Minio").Bind(minio);
//});
});
});
}
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"))
{
Configure<AbpTextTemplatingCachingOptions>(options =>
{
options.IsDynamicTemplateDefinitionStoreEnabled = true;
});
}
}
private void ConfigureFeatureManagement(IConfiguration configuration)
{
if (configuration.GetValue<bool>("FeatureManagement:IsDynamicStoreEnabled"))
{
Configure<FeatureManagementOptions>(options =>
{
options.IsDynamicFeatureStoreEnabled = true;
});
}
Configure<FeatureManagementOptions>(options =>
{
options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = AbpSaasPermissions.Editions.ManageFeatures;
options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = AbpSaasPermissions.Tenants.ManageFeatures;
});
}
private void ConfigureSettingManagement(IConfiguration configuration)
{
if (configuration.GetValue<bool>("SettingManagement:IsDynamicStoreEnabled"))
{
Configure<SettingManagementOptions>(options =>
{
options.IsDynamicSettingStoreEnabled = true;
});
}
}
private void ConfigureWebhooksManagement(IConfiguration configuration)
{
if (configuration.GetValue<bool>("WebhooksManagement:IsDynamicStoreEnabled"))
{
Configure<WebhooksManagementOptions>(options =>
{
options.IsDynamicWebhookStoreEnabled = true;
});
}
}
/// <summary>
/// 配置数据导出
/// </summary>
private void ConfigureExporter()
{
Configure<AbpExporterMiniExcelOptions>(options =>
{
// options.MapExportSetting(typeof(BookDto), config =>
// {
// config.DynamicColumns = new[]
// {
// // 忽略某些字段
// new DynamicExcelColumn(nameof(BookDto.AuthorId)){ Ignore = true },
// new DynamicExcelColumn(nameof(BookDto.LastModificationTime)){ Ignore = true },
// new DynamicExcelColumn(nameof(BookDto.LastModifierId)){ Ignore = true },
// new DynamicExcelColumn(nameof(BookDto.CreationTime)){ Ignore = true },
// new DynamicExcelColumn(nameof(BookDto.CreatorId)){ Ignore = true },
// new DynamicExcelColumn(nameof(BookDto.Id)){ Ignore = true },
// };
// });
});
}
/// <summary>
/// 配置数据权限
/// </summary>
private void ConfigureEntityDataProtected()
{
// Configure<DataProtectionManagementOptions>(options =>
// {
// options.AddEntities(typeof(DemoResource),
// new[]
// {
// typeof(Book),
// });
// });
}
private void ConfigurePermissionManagement(IConfiguration configuration)
{
if (configuration.GetValue<bool>("PermissionManagement:IsDynamicStoreEnabled"))
{
Configure<PermissionManagementOptions>(options =>
{
options.IsDynamicPermissionStoreEnabled = true;
});
}
Configure<PermissionManagementOptions>(options =>
{
// Rename IdentityServer.Client.ManagePermissions
// See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs
options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpOpenIddictPermissions.Applications.ManagePermissions;
//if (configuration.GetValue<bool>("AuthServer:UseOpenIddict"))
//{
// options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpOpenIddictPermissions.Applications.ManagePermissions;
//}
//else
//{
// options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpIdentityServerPermissions.Clients.ManagePermissions;
//}
});
}
private void ConfigureNotificationManagement(IConfiguration configuration)
{
if (configuration.GetValue<bool>("NotificationsManagement:IsDynamicStoreEnabled"))
{
Configure<AbpNotificationsManagementOptions>(options =>
{
options.IsDynamicNotificationsStoreEnabled = true;
});
}
}
private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration)
{
var distributedLockEnabled = configuration["DistributedLock:IsEnabled"];
if (distributedLockEnabled.IsNullOrEmpty() || bool.Parse(distributedLockEnabled))
{
var redis = ConnectionMultiplexer.Connect(configuration["DistributedLock:Redis:Configuration"]);
services.AddSingleton<IDistributedLockProvider>(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase()));
}
}
private void ConfigureVirtualFileSystem()
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<MicroServiceApplicationsSingleModule>("LY.MicroService.Applications.Single");
});
}
private void ConfigureIdempotent()
{
Configure<AbpIdempotentOptions>(options =>
{
options.IsEnabled = true;
options.DefaultTimeout = 0;
});
}
private void ConfigureDbContext()
{
Configure<AbpDbContextOptions>(options =>
{
// AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题
// options.UseNpgsql();
options.UseMySQL();
});
}
private void ConfigureDataSeeder()
{
Configure<CustomIdentityResourceDataSeederOptions>(options =>
{
options.Resources.Add(new CustomIdentityResources.AvatarUrl());
});
}
private void ConfigureExceptionHandling()
{
// 自定义需要处理的异常
Configure<AbpExceptionHandlingOptions>(options =>
{
// 加入需要处理的异常类型
options.Handlers.Add<Volo.Abp.Data.AbpDbConcurrencyException>();
options.Handlers.Add<AbpInitializationException>();
options.Handlers.Add<OutOfMemoryException>();
options.Handlers.Add<System.Data.Common.DbException>();
options.Handlers.Add<global::Microsoft.EntityFrameworkCore.DbUpdateException>();
options.Handlers.Add<System.Data.DBConcurrencyException>();
});
// 自定义需要发送邮件通知的异常类型
Configure<AbpEmailExceptionHandlingOptions>(options =>
{
// 是否发送堆栈信息
options.SendStackTrace = true;
// 未指定异常接收者的默认接收邮件
// 指定自己的邮件地址
});
Configure<VoloAbpExceptionHandlingOptions>(options =>
{
options.SendStackTraceToClients = false;
options.SendExceptionsDetailsToClients = false;
});
}
private void ConfigureJsonSerializer(IConfiguration configuration)
{
// 统一时间日期格式
Configure<AbpJsonOptions>(options =>
{
var jsonConfiguration = configuration.GetSection("Json");
if (jsonConfiguration.Exists())
{
jsonConfiguration.Bind(options);
}
});
// 中文序列化的编码问题
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
}
private void ConfigureCaching(IConfiguration configuration)
{
Configure<AbpDistributedCacheOptions>(options =>
{
configuration.GetSection("DistributedCache").Bind(options);
});
Configure<RedisCacheOptions>(options =>
{
var redisConfig = ConfigurationOptions.Parse(options.Configuration);
options.ConfigurationOptions = redisConfig;
options.InstanceName = configuration["Redis:InstanceName"];
});
}
private void ConfigureMultiTenancy(IConfiguration configuration)
{
// 多租户
Configure<AbpMultiTenancyOptions>(options =>
{
options.IsEnabled = true;
});
var tenantResolveCfg = configuration.GetSection("App:Domains");
if (tenantResolveCfg.Exists())
{
Configure<AbpTenantResolveOptions>(options =>
{
var domains = tenantResolveCfg.Get<string[]>();
foreach (var domain in domains)
{
options.AddDomainTenantResolver(domain);
}
});
}
}
private void ConfigureAuditing(IConfiguration configuration)
{
Configure<AbpAuditingOptions>(options =>
{
options.ApplicationName = ApplicationName;
// 是否启用实体变更记录
var allEntitiesSelectorIsEnabled = configuration["Auditing:AllEntitiesSelector"];
if (allEntitiesSelectorIsEnabled.IsNullOrWhiteSpace() ||
(bool.TryParse(allEntitiesSelectorIsEnabled, out var enabled) && enabled))
{
options.EntityHistorySelectors.AddAllEntities();
}
});
}
private void ConfigureSwagger(IServiceCollection services)
{
// Swagger
services.AddSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "App API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Scheme = "bearer",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
},
new string[] { }
}
});
options.OperationFilter<TenantHeaderParamter>();
});
}
private void ConfigureIdentity(IConfiguration configuration)
{
// 增加配置文件定义,在新建租户时需要
Configure<IdentityOptions>(options =>
{
var identityConfiguration = configuration.GetSection("Identity");
if (identityConfiguration.Exists())
{
identityConfiguration.Bind(options);
}
});
Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
Configure<IdentitySessionCleanupOptions>(options =>
{
options.IsCleanupEnabled = true;
});
}
private void ConfigureMvcUiTheme()
{
Configure<AbpBundlingOptions>(options =>
{
//options.StyleBundles.Configure(
// LeptonXLiteThemeBundles.Styles.Global,
// bundle =>
// {
// bundle.AddFiles("/global-styles.css");
// }
//);
});
}
private void ConfigureLocalization()
{
Configure<AbpLocalizationOptions>(options =>
{
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
options
.AddLanguagesMapOrUpdate(
"vue-admin-element-ui",
new NameValue("zh-Hans", "zh"),
new NameValue("en", "en"));
// vben admin 语言映射
options
.AddLanguagesMapOrUpdate(
"vben-admin-ui",
new NameValue("zh_CN", "zh-Hans"));
options.Resources.Get<AbpSettingManagementResource>()
.AddBaseTypes(
typeof(IdentityResource),
typeof(AliyunResource),
typeof(TencentCloudResource),
typeof(WeChatResource),
typeof(PlatformResource),
typeof(AbpOpenIddictResource),
typeof(AbpIdentityServerResource));
options.UseAllPersistence();
});
Configure<AbpLocalizationCultureMapOptions>(options =>
{
var zhHansCultureMapInfo = new CultureMapInfo
{
TargetCulture = "zh-Hans",
SourceCultures = new string[] { "zh", "zh_CN", "zh-CN" }
};
options.CulturesMaps.Add(zhHansCultureMapInfo);
options.UiCulturesMaps.Add(zhHansCultureMapInfo);
});
}
private void ConfigureWrapper()
{
Configure<AbpWrapperOptions>(options =>
{
options.IsEnabled = true;
// options.IsWrapUnauthorizedEnabled = true;
options.IgnoreNamespaces.Add("Elsa");
});
}
private void PreConfigureWrapper()
{
//PreConfigure<AbpDaprClientProxyOptions>(options =>
//{
// options.ProxyRequestActions.Add(
// (appid, httprequestmessage) =>
// {
// httprequestmessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true");
// });
//});
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientActions.Add(
(_, _, client) =>
{
client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true");
});
});
}
private void ConfigureAuditing()
{
Configure<AbpAuditingOptions>(options =>
{
// options.IsEnabledForGetRequests = true;
options.ApplicationName = ApplicationName;
});
}
private void ConfigureUrls(IConfiguration configuration)
{
Configure<AppUrlOptions>(options =>
{
var applicationConfiguration = configuration.GetSection("App:Urls:Applications");
foreach (var appConfig in applicationConfiguration.GetChildren())
{
options.Applications[appConfig.Key].RootUrl = appConfig["RootUrl"];
foreach (var urlsConfig in appConfig.GetSection("Urls").GetChildren())
{
options.Applications[appConfig.Key].Urls[urlsConfig.Key] = urlsConfig.Value;
}
}
});
}
private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false)
{
Configure<AbpAntiForgeryOptions>(options =>
{
options.AutoValidate = false;
});
services.Replace<CookieAuthenticationHandler, AbpCookieAuthenticationHandler>(ServiceLifetime.Scoped);
services.AddAuthentication()
.AddAbpJwtBearer(options =>
{
configuration.GetSection("AuthServer").Bind(options);
options.Events ??= new JwtBearerEvents();
options.Events.OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/api/files")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
};
});
if (!isDevelopment)
{
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
services
.AddDataProtection()
.SetApplicationName("LINGYUN.Abp.Application")
.PersistKeysToStackExchangeRedis(redis, "LINGYUN.Abp.Application:DataProtection:Protection-Keys");
}
services.AddSameSiteCookiePolicy();
}
private void ConfigureCors(IServiceCollection services, IConfiguration configuration)
{
services.AddCors(options =>
{
options.AddPolicy(DefaultCorsPolicyName, builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.WithAbpWrapExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
private void ConfigureWeChat()
{
Configure<AbpWeChatMessageHandleOptions>(options =>
{
// 回复文本消息
options.MapMessage<
LINGYUN.Abp.WeChat.Official.Messages.Models.TextMessage,
TextMessageReplyContributor>();
// 处理关注事件
options.MapEvent<
LINGYUN.Abp.WeChat.Official.Messages.Models.UserSubscribeEvent,
UserSubscribeEventContributor>();
options.MapMessage<
LINGYUN.Abp.WeChat.Work.Common.Messages.Models.TextMessage,
WeChat.Work.Messages.TextMessageReplyContributor>();
});
}
}

394
aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs

@ -0,0 +1,394 @@
using LINGYUN.Abp.Account;
using LINGYUN.Abp.Account.Templates;
using LINGYUN.Abp.Aliyun.SettingManagement;
using LINGYUN.Abp.AspNetCore.HttpOverrides;
using LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper;
using LINGYUN.Abp.AspNetCore.Mvc.Localization;
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper;
using LINGYUN.Abp.Auditing;
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;
using LINGYUN.Abp.FeatureManagement;
using LINGYUN.Abp.FeatureManagement.HttpApi;
using LINGYUN.Abp.Features.LimitValidation;
using LINGYUN.Abp.Features.LimitValidation.Redis.Client;
using LINGYUN.Abp.Http.Client.Wrapper;
using LINGYUN.Abp.Identity;
using LINGYUN.Abp.Identity.AspNetCore.Session;
using LINGYUN.Abp.Identity.EntityFrameworkCore;
using LINGYUN.Abp.Identity.Notifications;
using LINGYUN.Abp.Identity.OrganizaztionUnits;
using LINGYUN.Abp.Identity.Session.AspNetCore;
using LINGYUN.Abp.Identity.WeChat;
using LINGYUN.Abp.IdGenerator;
using LINGYUN.Abp.IM.SignalR;
using LINGYUN.Abp.Localization.CultureMap;
using LINGYUN.Abp.Localization.Persistence;
using LINGYUN.Abp.LocalizationManagement;
using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore;
using LINGYUN.Abp.MessageService;
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using LINGYUN.Abp.MultiTenancy.Editions;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.Notifications.Common;
using LINGYUN.Abp.Notifications.Emailing;
using LINGYUN.Abp.Notifications.EntityFrameworkCore;
using LINGYUN.Abp.Notifications.SignalR;
using LINGYUN.Abp.Notifications.WeChat.MiniProgram;
using LINGYUN.Abp.OpenApi.Authorization;
using LINGYUN.Abp.OpenIddict;
using LINGYUN.Abp.OpenIddict.AspNetCore;
using LINGYUN.Abp.OpenIddict.AspNetCore.Session;
using LINGYUN.Abp.OpenIddict.Portal;
using LINGYUN.Abp.OpenIddict.Sms;
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;
using LINGYUN.Abp.PermissionManagement.OrganizationUnits;
using LINGYUN.Abp.Saas;
using LINGYUN.Abp.Saas.EntityFrameworkCore;
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;
using LINGYUN.Abp.TextTemplating.EntityFrameworkCore;
using LINGYUN.Abp.UI.Navigation;
using LINGYUN.Abp.UI.Navigation.VueVbenAdmin;
using LINGYUN.Abp.Webhooks;
using LINGYUN.Abp.Webhooks.EventBus;
using LINGYUN.Abp.Webhooks.Identity;
using LINGYUN.Abp.Webhooks.Saas;
using LINGYUN.Abp.WebhooksManagement;
using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
using LINGYUN.Abp.WeChat.MiniProgram;
using LINGYUN.Abp.WeChat.Official;
using LINGYUN.Abp.WeChat.Official.Handlers;
using LINGYUN.Abp.WeChat.SettingManagement;
using LINGYUN.Abp.WeChat.Work;
using LINGYUN.Abp.WeChat.Work.Handlers;
using LINGYUN.Platform;
using LINGYUN.Platform.EntityFrameworkCore;
using LINGYUN.Platform.HttpApi;
using LINGYUN.Platform.Settings.VueVbenAdmin;
using LINGYUN.Platform.Theme.VueVbenAdmin;
using Volo.Abp;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
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.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using Volo.Abp.EventBus;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Imaging;
using Volo.Abp.Modularity;
using Volo.Abp.OpenIddict.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.PermissionManagement.OpenIddict;
using Volo.Abp.SettingManagement;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Threading;
// using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql;
using Volo.Abp.EntityFrameworkCore.MySQL;
namespace LY.AIO.Applications.Single;
[DependsOn(
typeof(AbpAccountApplicationModule),
typeof(AbpAccountHttpApiModule),
typeof(AbpAccountWebOpenIddictModule),
typeof(AbpAuditingApplicationModule),
typeof(AbpAuditingHttpApiModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpCachingManagementStackExchangeRedisModule),
typeof(AbpCachingManagementApplicationModule),
typeof(AbpCachingManagementHttpApiModule),
typeof(AbpIdentityAspNetCoreSessionModule),
typeof(AbpIdentitySessionAspNetCoreModule),
typeof(AbpIdentityNotificationsModule),
typeof(AbpIdentityDomainModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpIdentityHttpApiModule),
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpLocalizationManagementDomainModule),
typeof(AbpLocalizationManagementApplicationModule),
typeof(AbpLocalizationManagementHttpApiModule),
typeof(AbpLocalizationManagementEntityFrameworkCoreModule),
typeof(AbpSerilogEnrichersApplicationModule),
typeof(AbpSerilogEnrichersUniqueIdModule),
typeof(AbpMessageServiceDomainModule),
typeof(AbpMessageServiceApplicationModule),
typeof(AbpMessageServiceHttpApiModule),
typeof(AbpMessageServiceEntityFrameworkCoreModule),
typeof(AbpNotificationsDomainModule),
typeof(AbpNotificationsApplicationModule),
typeof(AbpNotificationsHttpApiModule),
typeof(AbpNotificationsEntityFrameworkCoreModule),
//typeof(AbpIdentityServerSessionModule),
//typeof(AbpIdentityServerApplicationModule),
//typeof(AbpIdentityServerHttpApiModule),
//typeof(AbpIdentityServerEntityFrameworkCoreModule),
typeof(AbpOpenIddictAspNetCoreModule),
typeof(AbpOpenIddictAspNetCoreSessionModule),
typeof(AbpOpenIddictApplicationModule),
typeof(AbpOpenIddictHttpApiModule),
typeof(AbpOpenIddictEntityFrameworkCoreModule),
typeof(AbpOpenIddictSmsModule),
typeof(AbpOpenIddictPortalModule),
typeof(AbpOpenIddictWeChatModule),
typeof(AbpOpenIddictWeChatWorkModule),
//typeof(AbpOssManagementMinioModule), // 取消注释以使用Minio
typeof(AbpOssManagementFileSystemModule),
// typeof(AbpOssManagementImagingModule),
typeof(AbpOssManagementDomainModule),
typeof(AbpOssManagementApplicationModule),
typeof(AbpOssManagementHttpApiModule),
typeof(AbpOssManagementSettingManagementModule),
typeof(AbpImagingImageSharpModule),
typeof(PlatformDomainModule),
typeof(PlatformApplicationModule),
typeof(PlatformHttpApiModule),
typeof(PlatformEntityFrameworkCoreModule),
typeof(PlatformSettingsVueVbenAdminModule),
typeof(PlatformThemeVueVbenAdminModule),
typeof(AbpUINavigationVueVbenAdminModule),
typeof(AbpSaasDomainModule),
typeof(AbpSaasApplicationModule),
typeof(AbpSaasHttpApiModule),
typeof(AbpSaasEntityFrameworkCoreModule),
typeof(TaskManagementDomainModule),
typeof(TaskManagementApplicationModule),
typeof(TaskManagementHttpApiModule),
typeof(TaskManagementEntityFrameworkCoreModule),
typeof(AbpTextTemplatingDomainModule),
typeof(AbpTextTemplatingApplicationModule),
typeof(AbpTextTemplatingHttpApiModule),
typeof(AbpTextTemplatingEntityFrameworkCoreModule),
typeof(AbpWebhooksModule),
typeof(AbpWebhooksEventBusModule),
typeof(AbpWebhooksIdentityModule),
typeof(AbpWebhooksSaasModule),
typeof(WebhooksManagementDomainModule),
typeof(WebhooksManagementApplicationModule),
typeof(WebhooksManagementHttpApiModule),
typeof(WebhooksManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementApplicationModule),
typeof(AbpFeatureManagementHttpApiModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementDomainModule),
typeof(AbpSettingManagementApplicationModule),
typeof(AbpSettingManagementHttpApiModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementApplicationModule),
typeof(AbpPermissionManagementHttpApiModule),
typeof(AbpPermissionManagementDomainIdentityModule),
typeof(AbpPermissionManagementDomainOpenIddictModule),
// typeof(AbpPermissionManagementDomainIdentityServerModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理
// typeof(AbpEntityFrameworkCorePostgreSqlModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAliyunSmsModule),
typeof(AbpAliyunSettingManagementModule),
typeof(AbpAuthenticationQQModule),
typeof(AbpAuthenticationWeChatModule),
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),
typeof(AbpFeaturesValidationRedisClientModule),
typeof(AbpAspNetCoreMvcLocalizationModule),
typeof(AbpLocalizationCultureMapModule),
typeof(AbpLocalizationPersistenceModule),
typeof(AbpOpenApiAuthorizationModule),
typeof(AbpIMSignalRModule),
typeof(AbpNotificationsModule),
typeof(AbpNotificationsCommonModule),
typeof(AbpNotificationsSignalRModule),
typeof(AbpNotificationsEmailingModule),
typeof(AbpMultiTenancyEditionsModule),
typeof(AbpTencentQQModule),
typeof(AbpTencentCloudSettingManagementModule),
typeof(AbpIdentityWeChatModule),
typeof(AbpNotificationsWeChatMiniProgramModule),
typeof(AbpWeChatMiniProgramModule),
typeof(AbpWeChatOfficialModule),
typeof(AbpWeChatOfficialApplicationModule),
typeof(AbpWeChatOfficialHttpApiModule),
typeof(AbpWeChatWorkModule),
typeof(AbpWeChatWorkApplicationModule),
typeof(AbpWeChatWorkHttpApiModule),
typeof(AbpWeChatOfficialHandlersModule),
typeof(AbpWeChatWorkHandlersModule),
typeof(AbpWeChatSettingManagementModule),
typeof(AbpDataDbMigratorModule),
typeof(AbpIdGeneratorModule),
typeof(AbpUINavigationModule),
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),
typeof(AbpHttpClientWrapperModule),
typeof(AbpAspNetCoreMvcWrapperModule),
typeof(AbpAspNetCoreMvcIdempotentWrapperModule),
typeof(AbpAspNetCoreHttpOverridesModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpEventBusModule),
typeof(AbpAutofacModule)
)]
public partial class MicroServiceApplicationsSingleModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var hostingEnvironment = context.Services.GetHostingEnvironment();
PreConfigureWrapper();
PreConfigureFeature();
PreConfigureIdentity();
PreConfigureApp(configuration);
PreConfigureQuartz(configuration);
PreConfigureAuthServer(configuration);
PreConfigureElsa(context.Services, configuration);
PreConfigureCertificate(configuration, hostingEnvironment);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
ConfigureWeChat();
ConfigureWrapper();
ConfigureExporter();
ConfigureAuditing();
ConfigureDbContext();
ConfigureIdempotent();
ConfigureMvcUiTheme();
ConfigureDataSeeder();
ConfigureLocalization();
ConfigureKestrelServer();
ConfigureBackgroundTasks();
ConfigureExceptionHandling();
ConfigureVirtualFileSystem();
ConfigureEntityDataProtected();
ConfigureUrls(configuration);
ConfigureCaching(configuration);
ConfigureAuditing(configuration);
ConfigureIdentity(configuration);
ConfigureAuthServer(configuration);
ConfigureSwagger(context.Services);
ConfigureEndpoints(context.Services);
ConfigureBlobStoring(configuration);
ConfigureMultiTenancy(configuration);
ConfigureJsonSerializer(configuration);
ConfigureTextTemplating(configuration);
ConfigureFeatureManagement(configuration);
ConfigureSettingManagement(configuration);
ConfigureWebhooksManagement(configuration);
ConfigurePermissionManagement(configuration);
ConfigureNotificationManagement(configuration);
ConfigureCors(context.Services, configuration);
ConfigureDistributedLock(context.Services, configuration);
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment());
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
AsyncHelper.RunSync(async () => await OnApplicationInitializationAsync(context));
}
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
await context.ServiceProvider.GetRequiredService<IDataSeeder>().SeedAsync(); ;
}
}

67
aspnet-core/services/LY.AIO.Applications.Single/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs

@ -0,0 +1,67 @@
namespace LY.AIO.Applications.Single.Microsoft.Extensions.DependencyInjection
{
public static class SameSiteCookiesServiceCollectionExtensions
{
public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking stack
if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
}
}

10
aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/ITenantConfigurationCache.cs

@ -0,0 +1,10 @@
using Volo.Abp.MultiTenancy;
namespace LY.AIO.Applications.Single.MultiTenancy;
public interface ITenantConfigurationCache
{
Task RefreshAsync();
Task<List<TenantConfiguration>> GetTenantsAsync();
}

59
aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCache.cs

@ -0,0 +1,59 @@
using LINGYUN.Abp.Saas.Tenants;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LY.AIO.Applications.Single.MultiTenancy;
public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency
{
protected ITenantRepository TenantRepository { get; }
protected IDistributedCache<TenantConfigurationCacheItem> TenantCache { get; }
public TenantConfigurationCache(
ITenantRepository tenantRepository,
IDistributedCache<TenantConfigurationCacheItem> tenantCache)
{
TenantRepository = tenantRepository;
TenantCache = tenantCache;
}
public async virtual Task RefreshAsync()
{
var cacheKey = GetCacheKey();
await TenantCache.RemoveAsync(cacheKey);
}
public async virtual Task<List<TenantConfiguration>> GetTenantsAsync()
{
return (await GetForCacheItemAsync()).Tenants;
}
protected async virtual Task<TenantConfigurationCacheItem> GetForCacheItemAsync()
{
var cacheKey = GetCacheKey();
var cacheItem = await TenantCache.GetAsync(cacheKey);
if (cacheItem == null)
{
var allActiveTenants = await TenantRepository.GetListAsync();
cacheItem = new TenantConfigurationCacheItem(
allActiveTenants
.Where(t => t.IsActive)
.Select(t => new TenantConfiguration(t.Id, t.Name)
{
IsActive = t.IsActive,
}).ToList());
await TenantCache.SetAsync(cacheKey, cacheItem);
}
return cacheItem;
}
protected virtual string GetCacheKey()
{
return "_Abp_Tenant_Configuration";
}
}

19
aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCacheItem.cs

@ -0,0 +1,19 @@
using Volo.Abp.MultiTenancy;
namespace LY.AIO.Applications.Single.MultiTenancy;
[IgnoreMultiTenancy]
public class TenantConfigurationCacheItem
{
public List<TenantConfiguration> Tenants { get; set; }
public TenantConfigurationCacheItem()
{
Tenants = new List<TenantConfiguration>();
}
public TenantConfigurationCacheItem(List<TenantConfiguration> tenants)
{
Tenants = tenants;
}
}

103
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml

@ -0,0 +1,103 @@
@using Volo.Abp.Account.Localization
@using Volo.Abp.Users
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
@using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.Data
@using Volo.Abp.Identity.Settings
@using Volo.Abp.Localization
@using Volo.Abp.Settings
@using Volo.Abp.ObjectExtending
@inject IHtmlLocalizer<AccountResource> L
@inject ICurrentUser CurrentUser
@inject ISettingProvider SettingManager
@inject IThemeManager ThemeManager
@inject IStringLocalizerFactory StringLocalizerFactory
@model Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo.AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel
@{
var isUserNameUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled), "true",
StringComparison.OrdinalIgnoreCase);
var isEmailUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled), "true",
StringComparison.OrdinalIgnoreCase);
}
<h4>@L["PersonalSettings"]</h4><hr/>
<form method="post" id="PersonalSettingsForm">
<input asp-for="ConcurrencyStamp" />
<abp-input asp-for="UserName" readonly="!isUserNameUpdateEnabled"/>
<abp-row>
<abp-column size-md="_6">
<abp-input asp-for="Name"/>
</abp-column>
<abp-column size-md="_6">
<abp-input asp-for="Surname"/>
</abp-column>
</abp-row>
<abp-row>
<abp-column size-md="_9">
<abp-input asp-for="Email" readonly="!isEmailUpdateEnabled"/>
</abp-column>
<abp-column size-md="_3">
@if (CurrentUser.EmailVerified)
{
<abp-button button-type="Success" text="@L["Confirmed"].Value"/>
}
else
{
@*<abp-button href="/Account/SendEmailConfirm" button-type="Link" text="@L["Validation"].Value" />*@
<a href="/Account/SendEmailConfirm">@L["Validation"].Value</a>
}
</abp-column>
</abp-row>
<abp-input asp-for="PhoneNumber"/>
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel>())
{
var isAllowed = propertyInfo.Configuration.GetOrDefault(IdentityModuleExtensionConsts.ConfigurationNames.AllowUserToEdit);
if (isAllowed == null || !isAllowed.Equals(true))
{
continue;
}
if (!propertyInfo.Name.EndsWith("_Text"))
{
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty())
{
if (propertyInfo.Type.IsEnum)
{
Model.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type);
}
<abp-select asp-for="ExtraProperties[propertyInfo.Name]"
name="ExtraProperties.@propertyInfo.Name"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
autocomplete-api-url="@propertyInfo.Lookup.Url"
autocomplete-selected-item-name="@Model.GetProperty(propertyInfo.Name + "_Text")"
autocomplete-selected-item-value="@Model.GetProperty(propertyInfo.Name)"
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName"
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName"
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName"
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName">
</abp-select>
}
else
{
<abp-input type="@propertyInfo.GetInputType()"
asp-for="ExtraProperties[propertyInfo.Name]"
name="ExtraProperties.@propertyInfo.Name"
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)"
asp-format="@propertyInfo.GetInputFormatOrNull()"
value="@propertyInfo.GetInputValueOrNull(Model.GetProperty(propertyInfo.Name))" />
}
}
}
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/>
</form>

28
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js

@ -0,0 +1,28 @@
(function ($) {
$(function () {
var l = abp.localization.getResource("AbpAccount");
$('#PersonalSettingsForm').submit(function (e) {
e.preventDefault();
if (!$('#PersonalSettingsForm').valid()) {
return false;
}
var input = $('#PersonalSettingsForm').serializeFormToObject();
volo.abp.account.profile.update(input).then(function (result) {
abp.notify.success(l('PersonalSettingsSaved'));
updateConcurrencyStamp();
});
});
});
abp.event.on('passwordChanged', updateConcurrencyStamp);
function updateConcurrencyStamp(){
volo.abp.account.profile.get().then(function(profile){
$("#ConcurrencyStamp").val(profile.concurrencyStamp);
});
}
})(jQuery);

17
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml

@ -0,0 +1,17 @@
@page
@inject IHtmlLocalizer<AccountResource> L
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@model LY.AIO.Applications.Single.Pages.Account.EmailConfirmModel
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<h4>@L["EmailConfirm"]</h4>
<form method="post">
<abp-input asp-for="UserId"/>
<abp-input asp-for="ConfirmToken"/>
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a>
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/>
</form>
</div>
</div>

72
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml.cs

@ -0,0 +1,72 @@
using LINGYUN.Abp.Account;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Web.Pages.Account;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace LY.AIO.Applications.Single.Pages.Account
{
public class EmailConfirmModel : AccountPageModel
{
[Required]
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid UserId { get; set; }
[Required]
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ConfirmToken { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public IMyProfileAppService MyProfileAppService { get; set; }
public EmailConfirmModel()
{
LocalizationResourceType = typeof(AccountResource);
}
public async virtual Task<IActionResult> OnPostAsync()
{
try
{
ValidateModel();
await MyProfileAppService.ConfirmEmailAsync(
new ConfirmEmailInput
{
ConfirmToken = ConfirmToken,
});
}
catch (AbpIdentityResultException e)
{
if (!string.IsNullOrWhiteSpace(e.Message))
{
Alerts.Warning(GetLocalizeExceptionMessage(e));
return Page();
}
throw;
}
catch (AbpValidationException)
{
return Page();
}
return RedirectToPage("./ConfirmEmailConfirmation", new
{
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
}
}
}

13
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml

@ -0,0 +1,13 @@
@page
@model LY.AIO.Applications.Single.Pages.Account.EmailConfirmConfirmationModel
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@inject IHtmlLocalizer<AccountResource> L
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<h4>@L["EmailConfirm"]</h4>
<p>@L["YourEmailIsSuccessfullyConfirm"]</p>
<a abp-button="Primary" href="@Url.Content(Model.ReturnUrl)">@L["GoToTheApplication"]</a>
</div>
</div>

22
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml.cs

@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Account.Web.Pages.Account;
namespace LY.AIO.Applications.Single.Pages.Account;
[AllowAnonymous]
public class EmailConfirmConfirmationModel : AccountPageModel
{
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public async virtual Task<IActionResult> OnGetAsync()
{
ReturnUrl = await GetRedirectUrlAsync(ReturnUrl, ReturnUrlHash);
return Page();
}
}

26
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml

@ -0,0 +1,26 @@
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@model LY.AIO.Applications.Single.Pages.Account.SendCodeModel
@inject IHtmlLocalizer<AccountResource> L
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<h4>@L["TwoFactor"]</h4>
<form method="post" class="mt-4">
<abp-input asp-for="RememberMe" />
<input asp-for="ReturnUrl" />
<input asp-for="ReturnUrlHash" />
<div class="form-group">
<abp-select asp-for="Input.SelectedProvider" label="@L["SelectedProvider"].Value" asp-items="@Model.Providers"></abp-select>
</div>
<div class="d-grid gap-2">
<abp-button type="submit" button-type="Primary" class="mt-2 mb-3">@L["SendVerifyCode"]</abp-button>
</div>
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})">
<i class="fa fa-long-arrow-left"></i> @L["Login"]
</a>
</form>
</div>
</div>

125
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml.cs

@ -0,0 +1,125 @@
using LINGYUN.Abp.Account.Emailing;
using LINGYUN.Abp.Identity.Settings;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Volo.Abp;
using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Web.Pages.Account;
using Volo.Abp.Sms;
namespace LY.AIO.Applications.Single.Pages.Account
{
public class SendCodeModel : AccountPageModel
{
[BindProperty]
public SendCodeInputModel Input { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public bool RememberMe { get; set; }
public IEnumerable<SelectListItem> Providers { get; set; }
protected ISmsSender SmsSender { get; }
protected IAccountEmailVerifySender AccountEmailVerifySender { get; }
public SendCodeModel(
ISmsSender smsSender,
IAccountEmailVerifySender accountEmailVerifySender)
{
SmsSender = smsSender;
AccountEmailVerifySender = accountEmailVerifySender;
LocalizationResourceType = typeof(AccountResource);
}
public virtual async Task<IActionResult> OnGetAsync()
{
Input = new SendCodeInputModel();
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
// ˫������Ϣ��֤ʧ��,һ�㶼�dz�ʱ�˻����û���Ϣ���
Alerts.Warning(L["TwoFactorAuthenticationInvaidUser"]);
return Page();
}
var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(user);
Providers = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
return Page();
}
public virtual async Task<IActionResult> OnPostAsync()
{
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
Alerts.Warning(L["TwoFactorAuthenticationInvaidUser"]);
return Page();
}
if (Input.SelectedProvider == "Authenticator")
{
// �û�ͨ���ʼ�/�������ӽ�����Ȩҳ��
return RedirectToPage("VerifyAuthenticatorCode", new
{
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash,
rememberMe = RememberMe
});
}
// ������֤��
var code = await UserManager.GenerateTwoFactorTokenAsync(user, Input.SelectedProvider);
if (string.IsNullOrWhiteSpace(code))
{
Alerts.Warning(L["InvaidGenerateTwoFactorToken"]);
return Page();
}
if (Input.SelectedProvider == "Email")
{
await AccountEmailVerifySender
.SendMailLoginVerifyCodeAsync(
code,
user.UserName,
user.Email);
}
else if (Input.SelectedProvider == "Phone")
{
var phoneNumber = await UserManager.GetPhoneNumberAsync(user);
var templateCode = await SettingProvider.GetOrNullAsync(IdentitySettingNames.User.SmsUserSignin);
Check.NotNullOrWhiteSpace(templateCode, nameof(IdentitySettingNames.User.SmsUserSignin));
// TODO: �Ժ���չ����ģ�巢��
var smsMessage = new SmsMessage(phoneNumber, code);
smsMessage.Properties.Add("code", code);
smsMessage.Properties.Add("TemplateCode", templateCode);
await SmsSender.SendAsync(smsMessage);
}
return RedirectToPage("VerifyCode", new
{
provider = Input.SelectedProvider,
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash,
rememberMe = RememberMe
});
}
}
public class SendCodeInputModel
{
public string SelectedProvider { get; set; }
}
}

16
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml

@ -0,0 +1,16 @@
@page
@inject IHtmlLocalizer<AccountResource> L
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@model LY.AIO.Applications.Single.Pages.Account.SendEmailConfirmModel
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<h4>@L["EmailConfirm"]</h4>
<form method="post">
<abp-input asp-for="Email" readonly="true" />
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a>
<abp-button type="submit" button-type="Primary" text="@L["ClickToValidation"].Value"/>
</form>
</div>
</div>

73
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml.cs

@ -0,0 +1,73 @@
using LINGYUN.Abp.Account;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Web.Pages.Account;
using Volo.Abp.Identity;
using Volo.Abp.Validation;
namespace LY.AIO.Applications.Single.Pages.Account
{
public class SendEmailConfirmModel : AccountPageModel
{
[BindProperty(SupportsGet = true)]
public string Email { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
public IMyProfileAppService MyProfileAppService { get; set; }
public SendEmailConfirmModel()
{
LocalizationResourceType = typeof(AccountResource);
}
public virtual Task<IActionResult> OnGetAsync()
{
Email = CurrentUser.Email;
return Task.FromResult<IActionResult>(Page());
}
public async virtual Task<IActionResult> OnPostAsync()
{
try
{
ValidateModel();
await MyProfileAppService.SendEmailConfirmLinkAsync(
new SendEmailConfirmCodeDto
{
Email = Email,
AppName = "MVC",
ReturnUrl = ReturnUrl,
ReturnUrlHash = ReturnUrlHash
});
}
catch (AbpIdentityResultException e)
{
if (!string.IsNullOrWhiteSpace(e.Message))
{
Alerts.Warning(GetLocalizeExceptionMessage(e));
return Page();
}
throw;
}
catch (AbpValidationException)
{
return Page();
}
return RedirectToPage("~/Account/Manage", new
{
returnUrl = ReturnUrl
});
}
}
}

63
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/TwoFactorSupportedLoginModel.cs

@ -0,0 +1,63 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.Account.Web;
using Volo.Abp.Account.Web.Pages.Account;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.OpenIddict;
using IdentityOptions = Microsoft.AspNetCore.Identity.IdentityOptions;
namespace LY.AIO.Applications.Single.Pages.Account
{
/// <summary>
/// 重写登录模型,实现双因素登录
/// </summary>
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(LoginModel), typeof(OpenIddictSupportedLoginModel))]
public class TwoFactorSupportedLoginModel : OpenIddictSupportedLoginModel
{
public TwoFactorSupportedLoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IOptions<IdentityOptions> identityOptions,
IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache,
AbpOpenIddictRequestHelper openIddictRequestHelper)
: base(schemeProvider, accountOptions, identityOptions, identityDynamicClaimsPrincipalContributorCache, openIddictRequestHelper)
{
}
protected async override Task<List<ExternalProviderModel>> GetExternalProviders()
{
var providers = await base.GetExternalProviders();
foreach (var provider in providers)
{
var localizedDisplayName = L[provider.DisplayName];
if (localizedDisplayName.ResourceNotFound)
{
localizedDisplayName = L["AuthenticationScheme:" + provider.DisplayName];
}
if (!localizedDisplayName.ResourceNotFound)
{
provider.DisplayName = localizedDisplayName.Value;
}
}
return providers;
}
protected override Task<IActionResult> TwoFactorLoginResultAsync()
{
// 重定向双因素认证页面
return Task.FromResult<IActionResult>(RedirectToPage("SendCode", new
{
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash,
rememberMe = LoginInput.RememberMe
}));
}
}
}

4
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml

@ -0,0 +1,4 @@
@page
@model LY.AIO.Applications.Single.Pages.Account.UseRecoveryCodeModel
@{
}

11
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml.cs

@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace LY.AIO.Applications.Single.Pages.Account
{
public class UseRecoveryCodeModel : PageModel
{
public void OnGet()
{
}
}
}

26
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml

@ -0,0 +1,26 @@
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@model LY.AIO.Applications.Single.Pages.Account.VerifyAuthenticatorCodeModel
@inject IHtmlLocalizer<AccountResource> L
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<form method="post" class="mt-4">
<input asp-for="RememberMe" />
<input asp-for="ReturnUrlHash" />
<div class="form-group">
<label asp-for="Input.VerifyCode"></label>
<input asp-for="Input.VerifyCode" class="form-control" />
<span asp-validation-for="Input.VerifyCode" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="RememberBrowser"></label>
<abp-input asp-for="RememberBrowser" />
</div>
<abp-button type="submit" button-type="Primary" class="btn-block btn-lg mt-3">@L["VerifyAuthenticatorCode"]</abp-button>
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})">
<i class="fa fa-long-arrow-left"></i> @L["Login"]
</a>
</form>
</div>
</div>

59
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml.cs

@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Account.Web.Pages.Account;
namespace LY.AIO.Applications.Single.Pages.Account
{
public class VerifyAuthenticatorCodeModel : AccountPageModel
{
[BindProperty]
public VerifyAuthenticatorCodeInputModel Input { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
[BindProperty(SupportsGet = true)]
public bool RememberBrowser { get; set; }
[HiddenInput]
public bool RememberMe { get; set; }
public virtual IActionResult OnGet()
{
Input = new VerifyAuthenticatorCodeInputModel();
return Page();
}
public virtual async Task<IActionResult> OnPostAsync()
{
var result = await SignInManager.TwoFactorAuthenticatorSignInAsync(Input.VerifyCode, RememberMe, RememberBrowser);
if (result.Succeeded)
{
return await RedirectSafelyAsync(ReturnUrl, ReturnUrlHash);
}
if (result.IsLockedOut)
{
Logger.LogWarning(7, "User account locked out.");
Alerts.Warning(L["UserLockedOutMessage"]);
return Page();
}
else
{
Alerts.Danger(L["TwoFactorAuthenticationInvaidUser"]);// TODO: ����״̬��Ľ��
return Page();
}
}
}
public class VerifyAuthenticatorCodeInputModel
{
[Required]
public string VerifyCode { get; set; }
}
}

29
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml

@ -0,0 +1,29 @@
@page
@inject IHtmlLocalizer<AccountResource> L
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Account.Localization
@model LY.AIO.Applications.Single.Pages.Account.VerifyCodeModel
<div class="card mt-3 shadow-sm rounded">
<div class="card-body p-5">
<form method="post" class="mt-4">
<input asp-for="Provider" />
<input asp-for="ReturnUrl" />
<input asp-for="ReturnUrlHash" />
<input asp-for="RememberMe" />
<div class="form-group">
<abp-input asp-for="Input.VerifyCode" label="@L["VerifyCode"].Value" class="form-control" />
</div>
<abp-row>
<abp-column>
<abp-input asp-for="Input.RememberBrowser" label="@L["RememberBrowser"].Value" />
</abp-column>
</abp-row>
<div class="d-grid gap-2">
<abp-button type="submit" button-type="Primary" class="mt-2 mb-3">@L["VerifyAuthenticatorCode"]</abp-button>
</div>
<a asp-page="./SendCode" asp-all-route-data="@(new Dictionary<string, string> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})">
<i class="fa fa-long-arrow-left"></i> @L["ReSendVerifyCode"]
</a>
</form>
</div>
</div>

90
aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml.cs

@ -0,0 +1,90 @@
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Web.Pages.Account;
namespace LY.AIO.Applications.Single.Pages.Account
{
public class VerifyCodeModel : AccountPageModel
{
[BindProperty]
public VerifyCodeInputModel Input { get; set; }
/// <summary>
/// ˫������֤�ṩ����
/// </summary>
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string Provider { get; set; }
/// <summary>
/// �ض���Url
/// </summary>
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; }
/// <summary>
///
/// </summary>
[HiddenInput]
[BindProperty(SupportsGet = true)]
public string ReturnUrlHash { get; set; }
/// <summary>
/// �Ƿ��ס��¼״̬
/// </summary>
[HiddenInput]
[BindProperty(SupportsGet = true)]
public bool RememberMe { get; set; }
public VerifyCodeModel()
{
LocalizationResourceType = typeof(AccountResource);
}
public virtual IActionResult OnGet()
{
Input = new VerifyCodeInputModel();
return Page();
}
public virtual async Task<IActionResult> OnPostAsync()
{
// ��֤�û���¼״̬
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
Alerts.Warning(L["TwoFactorAuthenticationInvaidUser"]);
return Page();
}
// ˫���ص�¼
var result = await SignInManager.TwoFactorSignInAsync(Provider, Input.VerifyCode, RememberMe, Input.RememberBrowser);
if (result.Succeeded)
{
return await RedirectSafelyAsync(ReturnUrl, ReturnUrlHash);
}
if (result.IsLockedOut)
{
Logger.LogWarning(7, "User account locked out.");
Alerts.Warning(L["UserLockedOutMessage"]);
return Page();
}
else
{
Alerts.Danger(L["TwoFactorAuthenticationInvaidUser"]);// TODO: ����״̬��Ľ��
return Page();
}
}
}
public class VerifyCodeInputModel
{
/// <summary>
/// �Ƿ���������м�ס��¼״̬
/// </summary>
public bool RememberBrowser { get; set; }
/// <summary>
/// ���͵���֤��
/// </summary>
[Required]
public string VerifyCode { get; set; }
}
}

36
aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml

@ -0,0 +1,36 @@
@page
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Alert
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
@using Volo.Abp.Users
@model LY.AIO.Applications.Single.Pages.IndexModel
@inject ICurrentUser CurrentUser
@if (CurrentUser.IsAuthenticated)
{
<div>
<abp-row>
<abp-column size-md="_3" class="text-center">
<i class="fa fa-user d-block" style="font-size: 10em; color: #12b900"></i>
<a abp-button="Primary" asp-controller="Logout" asp-action="Index" asp-area="Account">Logout</a>
</abp-column>
<abp-column size-md="_9">
<h2>@CurrentUser.UserName</h2>
<h5 class="text-muted">@CurrentUser.Email</h5>
<div>
<strong>Roles</strong>: @CurrentUser.Roles.JoinAsString(", ")
<br />
<strong>Claims</strong>: <br />
@Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString(" <br /> "))
</div>
</abp-column>
</abp-row>
</div>
}
@if (!CurrentUser.IsAuthenticated)
{
<div class="text-center">
<i class="fa fa-user d-block" style="font-size: 10em; color: #aaa"></i><br/><br />
<a abp-button="Primary" asp-page="/Account/Login">Login</a>
</div>
}

11
aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml.cs

@ -0,0 +1,11 @@
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
namespace LY.AIO.Applications.Single.Pages
{
public class IndexModel : AbpPageModel
{
public void OnGet()
{
}
}
}

4
aspnet-core/services/LY.AIO.Applications.Single/Pages/_ViewImports.cshtml

@ -0,0 +1,4 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling

82
aspnet-core/services/LY.AIO.Applications.Single/Program.cs

@ -0,0 +1,82 @@
using LINGYUN.Abp.Identity.Session.AspNetCore;
using LY.AIO.Applications.Single;
using Microsoft.AspNetCore.Cors;
using Serilog;
using Volo.Abp.IO;
using Volo.Abp.Modularity.PlugIns;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy
.WithOrigins(
builder.Configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.WithAbpWrapExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
builder.Host.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog((context, provider, config) =>
{
config.ReadFrom.Configuration(context.Configuration);
});
await builder.AddApplicationAsync<MicroServiceApplicationsSingleModule>(options =>
{
MicroServiceApplicationsSingleModule.ApplicationName = Environment.GetEnvironmentVariable("APPLICATION_NAME")
?? MicroServiceApplicationsSingleModule.ApplicationName;
options.ApplicationName = MicroServiceApplicationsSingleModule.ApplicationName;
options.Configuration.UserSecretsId = Environment.GetEnvironmentVariable("APPLICATION_USER_SECRETS_ID");
options.Configuration.UserSecretsAssembly = typeof(MicroServiceApplicationsSingleModule).Assembly;
var pluginFolder = Path.Combine(
Directory.GetCurrentDirectory(), "Modules");
DirectoryHelper.CreateIfNotExists(pluginFolder);
options.PlugInSources.AddFolder(
pluginFolder,
SearchOption.AllDirectories);
});
var app = builder.Build();
await app.InitializeApplicationAsync();
app.UseForwardedHeaders();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// app.UseAbpExceptionHandling();
app.UseCookiePolicy();
app.UseMapRequestLocalization();
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseMultiTenancy();
app.UseUnitOfWork();
app.UseAbpOpenIddictValidation();
app.UseAbpSession();
app.UseDynamicClaims();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support App API");
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
await app.RunAsync();

30
aspnet-core/services/LY.AIO.Applications.Single/Properties/launchSettings.json

@ -0,0 +1,30 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:19139",
"sslPort": 0
}
},
"profiles": {
"LY.MicroService.Applications.Single": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://0.0.0.0:30001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
"LY.MicroService.Applications.Single.Development": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://0.0.0.0:30000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

35
aspnet-core/services/LY.AIO.Applications.Single/TenantHeaderParamter.cs

@ -0,0 +1,35 @@
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.MultiTenancy;
namespace LY.AIO.Applications.Single;
public class TenantHeaderParamter : IOperationFilter
{
private readonly AbpMultiTenancyOptions _multiTenancyOptions;
private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions;
public TenantHeaderParamter(
IOptions<AbpMultiTenancyOptions> multiTenancyOptions,
IOptions<AbpAspNetCoreMultiTenancyOptions> aspNetCoreMultiTenancyOptions)
{
_multiTenancyOptions = multiTenancyOptions.Value;
_aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (_multiTenancyOptions.IsEnabled)
{
operation.Parameters = operation.Parameters ?? new List<OpenApiParameter>();
operation.Parameters.Add(new OpenApiParameter
{
Name = _aspNetCoreMultiTenancyOptions.TenantKey,
In = ParameterLocation.Header,
Description = "Tenant Id in http header",
Required = false
});
}
}
}

21
aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/TextMessageReplyContributor.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.WeChat.Common.Messages.Handlers;
using LINGYUN.Abp.WeChat.Official.Messages.Models;
using LINGYUN.Abp.WeChat.Official.Services;
namespace LY.AIO.Applications.Single.WeChat.Official.Messages;
/// <summary>
/// 文本消息客服回复
/// </summary>
public class TextMessageReplyContributor : IMessageHandleContributor<TextMessage>
{
public async virtual Task HandleAsync(MessageHandleContext<TextMessage> context)
{
var messageSender = context.ServiceProvider.GetRequiredService<IServiceCenterMessageSender>();
await messageSender.SendAsync(
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel(
context.Message.FromUserName,
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage(
context.Message.Content)));
}
}

21
aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/UserSubscribeEventContributor.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.WeChat.Common.Messages.Handlers;
using LINGYUN.Abp.WeChat.Official.Messages.Models;
using LINGYUN.Abp.WeChat.Official.Services;
namespace LY.AIO.Applications.Single.WeChat.Official.Messages;
/// <summary>
/// 用户关注回复消息
/// </summary>
public class UserSubscribeEventContributor : IEventHandleContributor<UserSubscribeEvent>
{
public async virtual Task HandleAsync(MessageHandleContext<UserSubscribeEvent> context)
{
var messageSender = context.ServiceProvider.GetRequiredService<IServiceCenterMessageSender>();
await messageSender.SendAsync(
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel(
context.Message.FromUserName,
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage(
"感谢您的关注, 点击菜单了解更多.")));
}
}

24
aspnet-core/services/LY.AIO.Applications.Single/WeChat/Work/Messages/TextMessageReplyContributor.cs

@ -0,0 +1,24 @@
using LINGYUN.Abp.WeChat.Common.Messages.Handlers;
using LINGYUN.Abp.WeChat.Work.Common.Messages.Models;
using LINGYUN.Abp.WeChat.Work.Messages;
namespace LY.AIO.Applications.Single.WeChat.Work.Messages;
/// <summary>
/// 文本消息客服回复
/// </summary>
public class TextMessageReplyContributor : IMessageHandleContributor<TextMessage>
{
public async virtual Task HandleAsync(MessageHandleContext<TextMessage> context)
{
var messageSender = context.ServiceProvider.GetRequiredService<IWeChatWorkMessageSender>();
await messageSender.SendAsync(
new LINGYUN.Abp.WeChat.Work.Messages.Models.WeChatWorkTextMessage(
context.Message.AgentId.ToString(),
new LINGYUN.Abp.WeChat.Work.Messages.Models.TextMessage(
context.Message.Content))
{
ToUser = context.Message.FromUserName,
});
}
}

249
aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json

@ -0,0 +1,249 @@
{
"App": {
"ShowPii": true,
"SelfUrl": "http://127.0.0.1:30001/",
"CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001",
"Urls": {
"Applications": {
"MVC": {
"RootUrl": "http://127.0.0.1:30001/",
"Urls": {
"Abp.Account.EmailConfirm": "Account/EmailConfirm",
"Abp.Account.EmailVerifyLogin": "Account/VerifyCode"
}
},
"STS": {
"RootUrl": "http://127.0.0.1:30001/"
},
"VueVbenAdmin": {
"RootUrl": "http://127.0.0.1:3100",
"Urls": {
"Abp.Account.EmailConfirm": "account/email-confirm"
}
}
}
}
},
"Auditing": {
"AllEntitiesSelector": true
},
"DistributedCache": {
"HideErrors": true,
"KeyPrefix": "LINGYUN.Abp.Application",
"GlobalCacheEntryOptions": {
"SlidingExpiration": "30:00:00",
"AbsoluteExpirationRelativeToNow": "60:00:00"
}
},
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//Mysql
// "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;"//Postgres
},
"DistributedLock": {
"IsEnabled": true,
"Redis": {
"Configuration": "127.0.0.1,defaultDatabase=14"
}
},
"Elsa": {
"Features": {
"DefaultPersistence": {
"Enabled": true,
"ConnectionStringIdentifier": "Default",
"EntityFrameworkCore": {
"MySql": {
"Enabled": true
}
}
},
"Console": true,
"Http": true,
"Email": true,
"TemporalQuartz": true,
"JavaScriptActivities": true,
"UserTask": true,
"Conductor": true,
"Telnyx": true,
"BlobStoring": true,
"Emailing": true,
"Notification": true,
"Sms": true,
"IM": true,
"PublishWebhook": true,
"Webhooks": {
"Enabled": true,
"ConnectionStringIdentifier": "Default",
"EntityFrameworkCore": {
"MySql": {
"Enabled": true
}
}
},
"WorkflowSettings": {
"Enabled": true,
"ConnectionStringIdentifier": "Default",
"EntityFrameworkCore": {
"MySql": {
"Enabled": true
}
}
}
},
"Server": {
"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": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456",
"quartz.dataSource.tkm.provider": "MySqlConnector",
// "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz",
// "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;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",
"InstanceName": "LINGYUN.Abp.Application"
},
"Features": {
"Validation": {
"Redis": {
"Configuration": "127.0.0.1,defaultDatabase=13",
"InstanceName": "LINGYUN.Abp.Application"
}
}
},
"AuthServer": {
"UseOpenIddict": true,
"Authority": "http://127.0.0.1:30001/",
"Audience": "lingyun-abp-application",
"RequireHttpsMetadata": false,
"SwaggerClientId": "InternalServiceClient",
"SwaggerClientSecret": "1q2w3E*"
},
"IdentityServer": {
"Clients": {
"VueAdmin": {
"ClientId": "vue-admin-client",
"RootUrl": "http://127.0.0.1:3100/"
},
"InternalService": {
"ClientId": "InternalServiceClient"
}
}
},
"OpenIddict": {
"Applications": {
"VueAdmin": {
"ClientId": "vue-admin-client",
"RootUrl": "http://127.0.0.1:3100/"
},
"InternalService": {
"ClientId": "InternalServiceClient"
}
},
"Lifetime": {
"AuthorizationCode": "00:05:00",
"AccessToken": "14:00:00",
"DeviceCode": "00:10:00",
"IdentityToken": "00:20:00",
"RefreshToken": "14:00:00",
"RefreshTokenReuseLeeway": "00:00:30",
"UserCode": "00:10:00"
}
},
"Identity": {
"Password": {
"RequiredLength": 6,
"RequiredUniqueChars": 0,
"RequireNonAlphanumeric": false,
"RequireLowercase": false,
"RequireUppercase": false,
"RequireDigit": false
},
"Lockout": {
"AllowedForNewUsers": false,
"LockoutDuration": 5,
"MaxFailedAccessAttempts": 5
},
"SignIn": {
"RequireConfirmedEmail": false,
"RequireConfirmedPhoneNumber": false
}
},
"FeatureManagement": {
"IsDynamicStoreEnabled": true
},
"SettingManagement": {
"IsDynamicStoreEnabled": true
},
"PermissionManagement": {
"IsDynamicStoreEnabled": true
},
"TextTemplating": {
"IsDynamicStoreEnabled": true
},
"WebhooksManagement": {
"IsDynamicStoreEnabled": true
},
"Logging": {
"Serilog": {
"Elasticsearch": {
"IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}"
}
}
},
"AuditLogging": {
"Elasticsearch": {
"IndexPrefix": "abp.dev.auditing"
}
},
"Elasticsearch": {
"NodeUris": "http://127.0.0.1:9200"
},
"Minio": {
"WithSSL": false,
"BucketName": "blobs",
"EndPoint": "127.0.0.1:19000",
"AccessKey": "ZD43kNpimiJf9mCuomTP",
"SecretKey": "w8IqMgi4Tnz0DGzN8jZ7IJWq7OEdbUnAU0jlZxQK",
"CreateBucketIfNotExists": false
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"DotNetCore": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Debug",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "Elasticsearch",
"Args": {
"nodeUris": "http://127.0.0.1:9200",
"indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}",
"autoRegisterTemplate": true,
"autoRegisterTemplateVersion": "ESv7"
}
}
]
}
}

89
aspnet-core/services/LY.AIO.Applications.Single/appsettings.json

@ -0,0 +1,89 @@
{
"Clock": {
"Kind": "Local"
},
"Forwarded": {
"ForwardedHeaders": "XForwardedFor,XForwardedProto"
},
"StringEncryption": {
"DefaultPassPhrase": "s46c5q55nxpeS8Ra",
"InitVectorBytes": "s83ng0abvd02js84",
"DefaultSalt": "sf&5)s3#"
},
"Json": {
"OutputDateTimeFormat": "yyyy-MM-dd HH:mm:ss",
"InputDateTimeFormats": [
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-ddTHH:mm:ss"
]
},
"AllowedHosts": "*",
"Hosting": {
"BasePath": ""
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"DotNetCore": "Information"
}
},
"Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Debug",
"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": {
"path": "Logs/Warn-.log",
"restrictedToMinimumLevel": "Warning",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "Logs/Error-.log",
"restrictedToMinimumLevel": "Error",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "Logs/Fatal-.log",
"restrictedToMinimumLevel": "Fatal",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}"
}
}
]
}
}

10
aspnet-core/services/LY.AIO.Applications.Single/gulpfile.js

@ -0,0 +1,10 @@
"use strict";
var gulp = require("gulp"),
path = require('path'),
copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js');
exports.default = function(done){
copyResources(path.resolve('./'));
done();
};

30
aspnet-core/templates/aio/PackageName.CompanyName.ProjectName.AIO.csproj

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>LINGYUN.Abp.AllInOne.Templates</PackageId>
<Version>8.3.0</Version>
<Authors>colin.in@foxmail.com</Authors>
<Description>Abp framework all-in-one template</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://github.com/colinin/abp-next-admin</PackageProjectUrl>
<PackageTags>allinone webapi cloud</PackageTags>
<PackageType>Template</PackageType>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/colinin/abp-next-admin</RepositoryUrl>
<DevelopmentDependency>true</DevelopmentDependency>
<IsPackable>true</IsPackable>
<IsShipping>true</IsShipping>
<IsShippingPackage>true</IsShippingPackage>
<IncludeBuildOutput>False</IncludeBuildOutput>
<IncludeSource>False</IncludeSource>
</PropertyGroup>
<ItemGroup>
<Content Include="content\**" Exclude="**/bin/**;**/obj/**;**/LocalNuget/**;**/.vs/**;**/.vscode/**;">
<Pack>true</Pack>
<PackagePath>content</PackagePath>
</Content>
</ItemGroup>
</Project>

115
aspnet-core/templates/aio/content/.template.config/template.json

@ -0,0 +1,115 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "colin.in@foxmail.com",
"classifications": ["allinone", "webapi", "cloud"],
"name": "LINGYUN.Abp.AllInOne",
"identity": "LINGYUN.Abp.AllInOne",
"description": "Abp framework all-in-one template",
"groupIdentity": "LINGYUN.Abp",
"shortName": "laa",
"tags": {
"language": "C#",
"type": "project"
},
"sources": [
{
"modifiers": [
{
"exclude": [
"**/[Bb]in/**",
"**/[Oo]bj/**",
"**/[Ll]ocalNuget/**",
".template.config/**/*",
".vs/**/*"
]
}
]
}
],
"sourceName": "ProjectName",
"preferNameDirectory": true,
"symbols": {
"AuthenticationScheme": {
"type": "parameter",
"description": "Authentication Scheme",
"datatype": "choice",
"defaultValue": "IdentityServer4",
"isRequired": false,
"choices": [
{
"choice": "IdentityServer4",
"description": "IdentityServer4"
},
{
"choice": "OpenIddict",
"description": "OpenIddict"
}
]
},
"DatabaseManagement": {
"type": "parameter",
"description": "Database Management",
"dataType": "choice",
"defaultValue": "MySQL",
"isRequired": false,
"choices": [
{
"choice": "SqlServer",
"description": "Sql Server"
},
{
"choice": "MySQL",
"description": "My SQL"
},
{
"choice": "Sqlite",
"description": "Sqlite"
},
{
"choice": "Oracle",
"description": "Oracle"
},
{
"choice": "OracleDevart",
"description": "Oracle Devart Driver"
},
{
"choice": "PostgreSql",
"description": "Postgre Sql"
}
]
},
"SqlServer": {
"type": "computed",
"value": "(DatabaseManagement == \"SqlServer\")"
},
"MySQL": {
"type": "computed",
"value": "(DatabaseManagement == \"MySQL\")"
},
"Sqlite": {
"type": "computed",
"value": "(DatabaseManagement == \"Sqlite\")"
},
"Oracle": {
"type": "computed",
"value": "(DatabaseManagement == \"Oracle\")"
},
"OracleDevart": {
"type": "computed",
"value": "(DatabaseManagement == \"Oracle.Devart\")"
},
"PostgreSql": {
"type": "computed",
"value": "(DatabaseManagement == \"PostgreSql\")"
},
"IdentityServer4": {
"type": "computed",
"value": "(AuthenticationScheme == \"IdentityServer4\")"
},
"OpenIddict": {
"type": "computed",
"value": "(AuthenticationScheme == \"OpenIddict\")"
}
}
}

0
aspnet-core/templates/content/.template.config/template.zh-Hans.json → aspnet-core/templates/aio/content/.template.config/template.zh-Hans.json

26
aspnet-core/templates/content/Directory.Build.props → aspnet-core/templates/aio/content/Directory.Build.props

@ -1,13 +1,13 @@
<Project>
<PropertyGroup>
<IsTestProject Condition="$(MSBuildProjectFullPath.Contains('test')) and ($(MSBuildProjectName.EndsWith('.Tests')) or $(MSBuildProjectName.EndsWith('.TestBase')))">true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Condition="'$(IsTestProject)' == 'true'" Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
<Project>
<PropertyGroup>
<IsTestProject Condition="$(MSBuildProjectFullPath.Contains('test')) and ($(MSBuildProjectName.EndsWith('.Tests')) or $(MSBuildProjectName.EndsWith('.TestBase')))">true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Condition="'$(IsTestProject)' == 'true'" Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

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

@ -0,0 +1,537 @@
<Project>
<PropertyGroup>
<DotNetCoreCAPPackageVersion>8.2.0</DotNetCoreCAPPackageVersion>
<ElsaPackageVersion>2.14.1</ElsaPackageVersion>
<VoloAbpPackageVersion>8.3.0</VoloAbpPackageVersion>
<LINGYUNAbpPackageVersion>8.3.0</LINGYUNAbpPackageVersion>
<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="LINGYUN.Abp.AspNetCore.HttpOverrides" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Localization" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AuditLogging" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.AuditLogging.Elasticsearch" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Authorization.OrganizationUnits" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Abstractions" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Jobs" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Data.DbMigrator" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtection" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtection.Abstractions" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtection.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.Domain.Shared" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dapr.Client" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dapr.Client.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elasticsearch" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.EntityChange.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.EntityChange.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.EntityChange.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.EventBus.CAP" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Emailing" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Http.Client.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.IdGenerator" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Session" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.Session.AspNetCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Localization.CultureMap" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MultiTenancy" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.Core" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.SignalR" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Notifications.WxPusher" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Rules" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Rules.RulesEngine" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Saas.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Serilog.Enrichers.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Serilog.Enrichers.UniqueId" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.TextTemplating.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.UI.Navigation" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.Core" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Webhooks.EventBus" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Linq.Dynamic.Queryable" Version="$(LINGYUNAbpPackageVersion)" />
</ItemGroup>
<!-- Abp Framework -->
<ItemGroup>
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="3.2.0" />
<PackageVersion Include="Volo.Abp.Core" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Web.IdentityServer" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Web.OpenIddict" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.MultiTenancy" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.Client.Common" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.NewtonsoftJson" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Serilog" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.SignalR" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.TestBase" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Auditing" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Auditing.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AuditLogging.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AuditLogging.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Authorization" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Authorization.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Autofac" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AutoMapper" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BackgroundJobs" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BackgroundJobs.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BackgroundWorkers" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BlobStoring" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.BlobStoring.FileSystem" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Caching" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Caching.StackExchangeRedis" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Cli.Core" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Data" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Ddd.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Ddd.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Ddd.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Ddd.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.DistributedLocking.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.DistributedLocking" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.MySql" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.Sqlite" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.Oracle" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.Oracle.Devart" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Features" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.FeatureManagement.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Emailing" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EventBus" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.EventBus.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.ExceptionHandling" Version="$(VoloAbpPackageVersion)" />
<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.Http.Client" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Http.Client.IdentityModel.Web" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.AspNetCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.IdentityServer.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.IdentityServer.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.IdentityServer.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.IdentityServer.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.IdentityServer.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.IdentityServer.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Identity.HttpApi.Client" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Imaging.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Imaging.ImageSharp" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Json" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Json.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Localization" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.MemoryDb" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.MultiTenancy" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.MultiTenancy.Abstractions" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.ObjectExtending" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.AspNetCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.OpenIddict.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.IdentityServer" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.PermissionManagement.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Quartz" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Security" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Settings" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.SettingManagement.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.SettingManagement.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.SettingManagement.Domain" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.SettingManagement.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.SettingManagement.HttpApi" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Swashbuckle" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Sms" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.TestBase" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.TextTemplating.Core" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.TextTemplating.Scriban" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Timing" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Threading" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Users.Abstractions" Version="$(VoloAbpPackageVersion)" />
<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.OpenIdConnect" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Protocols.Json" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="$(MicrosoftEntityFrameworkCorePackageVersion)" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="$(MicrosoftEntityFrameworkCorePackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.FileProviders.Physical" Version="$(MicrosoftExtensionsPackageVersion)" />
<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)" />
</ItemGroup>
<!-- Elsa -->
<ItemGroup>
<PackageVersion Include="Elsa" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Activities.Email" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Activities.Http" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Activities.UserTask" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Activities.Temporal.Quartz" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Core" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Designer.Components.Web" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Rebus.RabbitMq" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Server.Api" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Webhooks.Api" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.Webhooks.Persistence.EntityFramework.Core" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.WorkflowSettings.Persistence.EntityFramework.Core" Version="$(ElsaPackageVersion)" />
<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)" />
<PackageVersion Include="DotNetCore.CAP.Dashboard" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.MySql" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.OpenTelemetry" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.Oracle" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.PostgreSql" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.RabbitMQ" Version="$(DotNetCoreCAPPackageVersion)" />
<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.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.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)" />
</ItemGroup>
<!-- Fody -->
<ItemGroup>
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" />
<PackageVersion Include="Fody" Version="$(FodyPackageVersion)" />
</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="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.Features.LimitValidation.Redis.Client" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.RealTime" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Exporter.MiniExcel" Version="$(LINGYUNAbpPackageVersion)" />
<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.AspNetCore.Mvc.Idempotent.Wrapper" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenApi.Authorization" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.OpenApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.MultiTenancy.Editions" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Identity.WeChat" Version="$(LINGYUNAbpPackageVersion)" />
<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.Account.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Account.Templates" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Auditing.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Auditing.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Auditing.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Application.Contracts" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Application" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Domain" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.HttpApi" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.CachingManagement.StackExchangeRedis" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.BlobStoring" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Emailing" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.IM" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Notifications" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Sms" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Webhooks" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore" Version="$(LINGYUNAbpPackageVersion)" />
<PackageVersion Include="LINGYUN.Abp.Elsa.Server" Version="$(LINGYUNAbpPackageVersion)" />
<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.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.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)" />
</ItemGroup>
</Project>

0
aspnet-core/templates/content/NuGet.Config → aspnet-core/templates/aio/content/NuGet.Config

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

@ -0,0 +1,135 @@
# LINGYUN.Abp.Templates
[English](README.md) | [中文](README.zh-CN.md)
## Introduction
LINGYUN.Abp.Templates provides two types of project templates based on ABP Framework:
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.
## Features
### Common Features
- Integrated authentication (IdentityServer4/OpenIddict)
- Database integration (multiple databases supported)
- Unified configuration management
- Distributed event bus support
- Background job processing
### Microservice Template Features
- Complete microservice project structure
- Service discovery and registration
- Distributed deployment support
### All-in-One Template Features
- Simplified deployment
- Easier maintenance
- Lower resource requirements
## How to Use
### Install labp CLI Tool
```bash
dotnet tool install --global LINGYUN.Abp.Cli
```
### Install Templates
```bash
# Install Microservice Template
dotnet new install LINGYUN.Abp.MicroService.Templates
# Install All-in-One Template
dotnet new install LINGYUN.Abp.AllInOne.Templates
```
### Create New Project
#### For Microservice Project
```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
```
#### For All-in-One 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
```
## How to Run
After creating your project, you can run it using the following command:
### For Microservice Project
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.HttpApi.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
### For All-in-One Project
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.AIO.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
## How to Package and Publish
1. Clone the Project
```bash
git clone <repository-url>
cd <repository-path>/aspnet-core/templates/content
```
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`
```xml
<Version>8.3.0</Version>
```
3. Execute Packaging Script
```powershell
# Windows PowerShell
.\pack.ps1
# PowerShell Core (Windows/Linux/macOS)
pwsh pack.ps1
```
The script will prompt you to choose which template to package:
1. Microservice Template
2. All-in-One Template
3. Both Templates
## Supported Databases
- SqlServer
- MySQL
- PostgreSQL
- Oracle
- SQLite
## Notes
- 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

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

@ -0,0 +1,135 @@
# LINGYUN.Abp.Templates
[English](README.md) | [中文](README.zh-CN.md)
## 简介
LINGYUN.Abp.Templates 基于 ABP Framework 提供两种项目模板:
1. **微服务模板**:完整的分布式微服务架构模板
2. **单体应用模板**:将所有服务集成到一个项目中的单体应用模板
## 特性
### 共同特性
- 集成身份认证(支持 IdentityServer4/OpenIddict)
- 数据库集成(支持多种数据库)
- 统一配置管理
- 分布式事件总线支持
- 后台作业处理
### 微服务模板特性
- 完整的微服务项目结构
- 服务发现与注册
- 支持分布式部署
### 单体应用模板特性
- 简化的部署流程
- 更容易的维护
- 更低的资源需求
## 使用方法
### 安装模板
```bash
# 安装微服务模板:lam
dotnet new install LINGYUN.Abp.MicroService.Templates
# 安装单体应用模板:laa
dotnet new install LINGYUN.Abp.AllInOne.Templates
```
### 安装 labp 命令行工具
```bash
dotnet tool install --global LINGYUN.Abp.Cli
```
### 创建新项目
#### 创建微服务项目
```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
```
#### 创建单体应用项目
```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
```
## 运行项目
创建项目后,可以使用以下命令运行:
### 运行微服务项目
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.HttpApi.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
### 运行单体应用项目
```bash
cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.AIO.Host
dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development"
```
## 打包与发布
1. 克隆项目
```bash
git clone <repository-url>
cd <repository-path>/aspnet-core/templates/content
```
2. 修改版本号
编辑项目文件更新版本号:
- 微服务模板:`../PackageName.CompanyName.ProjectName.csproj`
- 单体应用模板:`../PackageName.CompanyName.ProjectName.AIO.csproj`
```xml
<Version>8.3.0</Version>
```
3. 执行打包脚本
```powershell
# Windows PowerShell
.\pack.ps1
# PowerShell Core (Windows/Linux/macOS)
pwsh pack.ps1
```
脚本会提示您选择要打包的模板:
1. 微服务模板
2. 单体应用模板
3. 两种模板都打包
## 支持的数据库
- SqlServer
- MySQL
- PostgreSQL
- Oracle
- SQLite
## 注意事项
- 确保已安装 .NET SDK 8.0 或更高版本
- 根据需求选择合适的模板:
- 微服务模板:适用于大规模分布式应用
- 单体应用模板:适用于小型应用或简单部署需求
- 打包时注意 NuGet 发布地址和密钥
- 发布前建议进行完整测试

74
aspnet-core/templates/content/common.props → aspnet-core/templates/aio/content/common.props

@ -1,38 +1,38 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>8.2.1</Version>
<Authors>colin</Authors>
<NoWarn>$(NoWarn);CS1591;CS0436;CS8618;NU1803</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>
<GeneratePackageOnBuild Condition="$(AssemblyName.StartsWith('LINGYUN'))">true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<Compile Remove="LocalNuget\**" />
<EmbeddedResource Remove="LocalNuget\**" />
<None Remove="LocalNuget\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Modules\**" />
<EmbeddedResource Remove="Modules\**" />
<None Remove="Modules\**" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>$(SolutionDir)LocalNuget</OutputPath>
</PropertyGroup>
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>8.2.1</Version>
<Authors>colin</Authors>
<NoWarn>$(NoWarn);CS1591;CS0436;CS8618;NU1803</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>
<GeneratePackageOnBuild Condition="$(AssemblyName.StartsWith('LINGYUN'))">true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<Compile Remove="LocalNuget\**" />
<EmbeddedResource Remove="LocalNuget\**" />
<None Remove="LocalNuget\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Modules\**" />
<EmbeddedResource Remove="Modules\**" />
<None Remove="Modules\**" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>$(SolutionDir)LocalNuget</OutputPath>
</PropertyGroup>
</Project>

0
aspnet-core/templates/content/configureawait.props → aspnet-core/templates/aio/content/configureawait.props

12
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "7.0.3",
"commands": [
"dotnet-ef"
]
}
}
}

2
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore

@ -0,0 +1,2 @@
wwwroot
package*.json

89
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs

@ -0,0 +1,89 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Options;
using System.Text.Encodings.Web;
namespace PackageName.CompanyName.ProjectName.AIO.Host.Authentication;
public class AbpCookieAuthenticationHandler : CookieAuthenticationHandler
{
public AbpCookieAuthenticationHandler(
IOptionsMonitor<CookieAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder) : base(options, logger, encoder)
{
}
public AbpCookieAuthenticationHandler(
IOptionsMonitor<CookieAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
{
}
protected const string XRequestFromHeader = "X-Request-From";
protected const string DontRedirectRequestFromHeader = "vben";
protected override Task InitializeEventsAsync()
{
var events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
},
OnRedirectToAccessDenied = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
},
OnRedirectToLogout = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
},
OnRedirectToReturnUrl = ctx =>
{
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal))
{
// ctx.Response.Headers.Location = ctx.RedirectUri;
ctx.Response.StatusCode = 401;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.CompletedTask;
}
};
Events = events;
return Task.CompletedTask;
}
}

38
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs

@ -0,0 +1,38 @@
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
namespace PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs;
public class NotificationPublishJob : AsyncBackgroundJob<NotificationPublishJobArgs>, ITransientDependency
{
protected AbpNotificationsPublishOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected INotificationDataSerializer NotificationDataSerializer { get; }
public NotificationPublishJob(
IOptions<AbpNotificationsPublishOptions> options,
IServiceScopeFactory serviceScopeFactory,
INotificationDataSerializer notificationDataSerializer)
{
Options = options.Value;
ServiceScopeFactory = serviceScopeFactory;
NotificationDataSerializer = notificationDataSerializer;
}
public override async Task ExecuteAsync(NotificationPublishJobArgs args)
{
var providerType = Type.GetType(args.ProviderType);
using (var scope = ServiceScopeFactory.CreateScope())
{
if (scope.ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider)
{
var store = scope.ServiceProvider.GetRequiredService<INotificationStore>();
var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId);
notification.Data = NotificationDataSerializer.Serialize(notification.Data);
await publishProvider.PublishAsync(notification, args.UserIdentifiers);
}
}
}
}

22
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs

@ -0,0 +1,22 @@
using LINGYUN.Abp.Notifications;
namespace PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs;
public class NotificationPublishJobArgs
{
public Guid? TenantId { get; set; }
public long NotificationId { get; set; }
public string ProviderType { get; set; }
public List<UserIdentifier> UserIdentifiers { get; set; }
public NotificationPublishJobArgs()
{
UserIdentifiers = new List<UserIdentifier>();
}
public NotificationPublishJobArgs(long id, string providerType, List<UserIdentifier> userIdentifiers, Guid? tenantId = null)
{
NotificationId = id;
ProviderType = providerType;
UserIdentifiers = userIdentifiers;
TenantId = tenantId;
}
}

11
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs

@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;
namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers;
public class HomeController : Controller
{
public IActionResult Index()
{
return Redirect("/swagger");
}
}

70
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs

@ -0,0 +1,70 @@
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers;
[ExposeServices(
typeof(SettingController),
typeof(SettingMergeController))]
public class SettingMergeController : SettingController
{
private readonly SettingManagementMergeOptions _mergeOptions;
public SettingMergeController(
ISettingAppService settingAppService,
ISettingTestAppService settingTestAppService,
IOptions<SettingManagementMergeOptions> mergeOptions)
: base(settingAppService, settingTestAppService)
{
_mergeOptions = mergeOptions.Value;
}
[HttpGet]
[Route("by-current-tenant")]
public async override Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
var result = new SettingGroupResult();
var markTypeMap = new List<Type>
{
typeof(SettingMergeController),
};
foreach (var serviceType in _mergeOptions.GlobalSettingProviders
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType))))
{
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IReadonlySettingAppService>();
var currentResult = await settingService.GetAllForCurrentTenantAsync();
foreach (var group in currentResult.Items)
{
result.AddGroup(group);
}
markTypeMap.Add(serviceType);
}
return result;
}
[HttpGet]
[Route("by-global")]
public async override Task<SettingGroupResult> GetAllForGlobalAsync()
{
var result = new SettingGroupResult();
var markTypeMap = new List<Type>
{
typeof(SettingMergeController),
};
foreach (var serviceType in _mergeOptions.GlobalSettingProviders
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType))))
{
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IReadonlySettingAppService>();
var currentResult = await settingService.GetAllForGlobalAsync();
foreach (var group in currentResult.Items)
{
result.AddGroup(group);
}
markTypeMap.Add(serviceType);
}
return result;
}
}

45
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs

@ -0,0 +1,45 @@
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers;
[ExposeServices(
typeof(UserSettingController),
typeof(UserSettingMergeController))]
public class UserSettingMergeController : UserSettingController
{
private readonly SettingManagementMergeOptions _mergeOptions;
public UserSettingMergeController(
IUserSettingAppService service,
IOptions<SettingManagementMergeOptions> mergeOptions)
: base(service)
{
_mergeOptions = mergeOptions.Value;
}
[HttpGet]
[Route("by-current-user")]
public async override Task<SettingGroupResult> GetAllForCurrentUserAsync()
{
var result = new SettingGroupResult();
var markTypeMap = new List<Type>
{
typeof(UserSettingMergeController),
};
foreach (var serviceType in _mergeOptions.UserSettingProviders
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType))))
{
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IUserSettingAppService>();
var currentResult = await settingService.GetAllForCurrentUserAsync();
foreach (var group in currentResult.Items)
{
result.AddGroup(group);
}
markTypeMap.Add(serviceType);
}
return result;
}
}

19
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile

@ -0,0 +1,19 @@
FROM mcr.microsoft.com/dotnet/aspnet:8.0
LABEL maintainer="colin.in@foxmail.com"
WORKDIR /app
COPY . /app
#东8区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone
EXPOSE 80/tcp
VOLUME [ "./app/blobs" ]
VOLUME [ "./app/Logs" ]
VOLUME [ "./app/Modules" ]
RUN apt update
RUN apt install wget -y
ENTRYPOINT ["dotnet", "PackageName.CompanyName.ProjectName.AIO.dll"]

59
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs

@ -0,0 +1,59 @@
using LINGYUN.Abp.IM;
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.RealTime;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed
{
public class ChatMessageEventHandler : IDistributedEventHandler<RealTimeEto<ChatMessage>>, ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<ChatMessageEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="AbpIMOptions"/>.
/// </summary>
protected AbpIMOptions Options { get; }
protected IMessageStore MessageStore { get; }
protected IMessageBlocker MessageBlocker { get; }
protected IMessageSenderProviderManager MessageSenderProviderManager { get; }
public ChatMessageEventHandler(
IOptions<AbpIMOptions> options,
IMessageStore messageStore,
IMessageBlocker messageBlocker,
IMessageSenderProviderManager messageSenderProviderManager)
{
Options = options.Value;
MessageStore = messageStore;
MessageBlocker = messageBlocker;
MessageSenderProviderManager = messageSenderProviderManager;
Logger = NullLogger<ChatMessageEventHandler>.Instance;
}
public async virtual Task HandleEventAsync(RealTimeEto<ChatMessage> eventData)
{
Logger.LogDebug($"Persistent chat message.");
var message = eventData.Data;
// 消息拦截
// 扩展敏感词汇过滤
await MessageBlocker.InterceptAsync(message);
await MessageStore.StoreMessageAsync(message);
// 发送消息
foreach (var provider in MessageSenderProviderManager.Providers)
{
Logger.LogDebug($"Sending message with provider {provider.Name}");
await provider.SendMessageAsync(message);
}
}
}
}

470
aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs

@ -0,0 +1,470 @@
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs;
using PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy;
using System.Globalization;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Json;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TextTemplating;
using Volo.Abp.Uow;
namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed
{
/// <summary>
/// 订阅通知发布事件,统一发布消息
/// </summary>
/// <remarks>
/// 作用在于SignalR客户端只会与一台服务器建立连接,
/// 只有启用了SignlR服务端的才能真正将消息发布到客户端
/// </remarks>
public class NotificationEventHandler :
IDistributedEventHandler<NotificationEto<NotificationData>>,
IDistributedEventHandler<NotificationEto<NotificationTemplate>>,
ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<NotificationEventHandler> Logger { get; set; }
/// <summary>
/// Reference to <see cref="AbpNotificationsPublishOptions"/>.
/// </summary>
protected AbpNotificationsPublishOptions Options { get; }
/// <summary>
/// Reference to <see cref="ICurrentTenant"/>.
/// </summary>
protected ICurrentTenant CurrentTenant { get; }
/// <summary>
/// Reference to <see cref="ITenantConfigurationCache"/>.
/// </summary>
protected ITenantConfigurationCache TenantConfigurationCache { get; }
/// <summary>
/// Reference to <see cref="IJsonSerializer"/>.
/// </summary>
protected IJsonSerializer JsonSerializer { get; }
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
protected IBackgroundJobManager BackgroundJobManager { get; }
/// <summary>
/// Reference to <see cref="ITemplateRenderer"/>.
/// </summary>
protected ITemplateRenderer TemplateRenderer { get; }
/// <summary>
/// Reference to <see cref="INotificationStore"/>.
/// </summary>
protected INotificationStore NotificationStore { get; }
/// <summary>
/// Reference to <see cref="IStringLocalizerFactory"/>.
/// </summary>
protected IStringLocalizerFactory StringLocalizerFactory { get; }
/// <summary>
/// Reference to <see cref="INotificationDataSerializer"/>.
/// </summary>
protected INotificationDataSerializer NotificationDataSerializer { get; }
/// <summary>
/// Reference to <see cref="INotificationDefinitionManager"/>.
/// </summary>
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationSubscriptionManager"/>.
/// </summary>
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
/// <summary>
/// Reference to <see cref="INotificationPublishProviderManager"/>.
/// </summary>
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
/// <summary>
/// Initializes a new instance of the <see cref="NotificationEventHandler"/> class.
/// </summary>
public NotificationEventHandler(
ICurrentTenant currentTenant,
ITenantConfigurationCache tenantConfigurationCache,
IJsonSerializer jsonSerializer,
ITemplateRenderer templateRenderer,
IBackgroundJobManager backgroundJobManager,
IStringLocalizerFactory stringLocalizerFactory,
IOptions<AbpNotificationsPublishOptions> options,
INotificationStore notificationStore,
INotificationDataSerializer notificationDataSerializer,
INotificationDefinitionManager notificationDefinitionManager,
INotificationSubscriptionManager notificationSubscriptionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
Options = options.Value;
TenantConfigurationCache = tenantConfigurationCache;
CurrentTenant = currentTenant;
JsonSerializer = jsonSerializer;
TemplateRenderer = templateRenderer;
BackgroundJobManager = backgroundJobManager;
StringLocalizerFactory = stringLocalizerFactory;
NotificationStore = notificationStore;
NotificationDataSerializer = notificationDataSerializer;
NotificationDefinitionManager = notificationDefinitionManager;
NotificationSubscriptionManager = notificationSubscriptionManager;
NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger<NotificationEventHandler>.Instance;
}
[UnitOfWork]
public async virtual Task HandleEventAsync(NotificationEto<NotificationTemplate> eventData)
{
var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name);
if (notification == null)
{
return;
}
var culture = eventData.Data.Culture;
if (culture.IsNullOrWhiteSpace())
{
culture = CultureInfo.CurrentCulture.Name;
}
using (CultureHelper.Use(culture, culture))
{
if (notification.NotificationType == NotificationType.System)
{
using (CurrentTenant.Change(null))
{
await SendToTenantAsync(null, notification, eventData);
var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync();
foreach (var activeTenant in allActiveTenants)
{
await SendToTenantAsync(activeTenant.Id, notification, eventData);
}
}
}
else
{
await SendToTenantAsync(eventData.TenantId, notification, eventData);
}
}
}
[UnitOfWork]
public async virtual Task HandleEventAsync(NotificationEto<NotificationData> eventData)
{
var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name);
if (notification == null)
{
return;
}
if (notification.NotificationType == NotificationType.System)
{
using (CurrentTenant.Change(null))
{
await SendToTenantAsync(null, notification, eventData);
var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync();
foreach (var activeTenant in allActiveTenants)
{
await SendToTenantAsync(activeTenant.Id, notification, eventData);
}
}
}
else
{
await SendToTenantAsync(eventData.TenantId, notification, eventData);
}
}
protected async virtual Task SendToTenantAsync(
Guid? tenantId,
NotificationDefinition notification,
NotificationEto<NotificationTemplate> eventData)
{
using (CurrentTenant.Change(tenantId))
{
var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers);
// 过滤用户指定提供者
if (eventData.UseProviders.Any())
{
providers = providers.Where(p => eventData.UseProviders.Contains(p.Name));
}
else if (notification.Providers.Any())
{
providers = providers.Where(p => notification.Providers.Contains(p.Name));
}
var notificationInfo = new NotificationInfo
{
Name = notification.Name,
TenantId = tenantId,
Severity = eventData.Severity,
Type = notification.NotificationType,
ContentType = notification.ContentType,
CreationTime = eventData.CreationTime,
Lifetime = notification.NotificationLifetime,
};
notificationInfo.SetId(eventData.Id);
var title = notification.DisplayName.Localize(StringLocalizerFactory);
var message = "";
try
{
// 由于模板通知受租户影响, 格式化失败的消息将被丢弃.
message = await TemplateRenderer.RenderAsync(
templateName: eventData.Data.Name,
model: eventData.Data.ExtraProperties,
cultureName: eventData.Data.Culture,
globalContext: new Dictionary<string, object>
{
// 模板不支持 $ 字符, 改为普通关键字
{ NotificationKeywords.Name, notification.Name },
{ NotificationKeywords.FormUser, eventData.Data.FormUser },
{ NotificationKeywords.Id, eventData.Id },
{ NotificationKeywords.Title, title.ToString() },
{ NotificationKeywords.CreationTime, eventData.CreationTime.ToString(Options.DateTimeFormat) },
});
}
catch(Exception ex)
{
Logger.LogWarning("Formatting template notification failed, message will be discarded, cause :{message}", ex.Message);
return;
}
var notificationData = new NotificationData();
notificationData.WriteStandardData(
title: title.ToString(),
message: message,
createTime: eventData.CreationTime,
formUser: eventData.Data.FormUser);
notificationData.ExtraProperties.AddIfNotContains(eventData.Data.ExtraProperties);
notificationInfo.Data = notificationData;
var subscriptionUsers = await GerSubscriptionUsersAsync(
notificationInfo.Name,
eventData.Users,
tenantId);
await PersistentNotificationAsync(
notificationInfo,
subscriptionUsers,
providers);
if (subscriptionUsers.Any())
{
// 发布通知
foreach (var provider in providers)
{
await PublishToSubscriberAsync(provider, notificationInfo, subscriptionUsers);
}
}
}
}
protected async virtual Task SendToTenantAsync(
Guid? tenantId,
NotificationDefinition notification,
NotificationEto<NotificationData> eventData)
{
using (CurrentTenant.Change(tenantId))
{
var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers);
// 过滤用户指定提供者
if (eventData.UseProviders.Any())
{
providers = providers.Where(p => eventData.UseProviders.Contains(p.Name));
}
else if (notification.Providers.Any())
{
providers = providers.Where(p => notification.Providers.Contains(p.Name));
}
var notificationInfo = new NotificationInfo
{
Name = notification.Name,
CreationTime = eventData.CreationTime,
Data = eventData.Data,
Severity = eventData.Severity,
Lifetime = notification.NotificationLifetime,
TenantId = tenantId,
Type = notification.NotificationType,
ContentType = notification.ContentType,
};
notificationInfo.SetId(eventData.Id);
notificationInfo.Data = NotificationDataSerializer.Serialize(notificationInfo.Data);
// 获取用户订阅
var subscriptionUsers = await GerSubscriptionUsersAsync(
notificationInfo.Name,
eventData.Users,
tenantId);
// 持久化通知
await PersistentNotificationAsync(
notificationInfo,
subscriptionUsers,
providers);
if (subscriptionUsers.Any())
{
// 发布订阅通知
foreach (var provider in providers)
{
await PublishToSubscriberAsync(provider, notificationInfo, subscriptionUsers);
}
}
}
}
/// <summary>
/// 获取用户订阅列表
/// </summary>
/// <param name="notificationName">通知名称</param>
/// <param name="sendToUsers">接收用户列表</param>
/// <param name="tenantId">租户标识</param>
/// <returns>用户订阅列表</returns>
protected async Task<IEnumerable<UserIdentifier>> GerSubscriptionUsersAsync(
string notificationName,
IEnumerable<UserIdentifier> sendToUsers,
Guid? tenantId = null)
{
try
{
// 获取用户订阅列表
var userSubscriptions = await NotificationSubscriptionManager.GetUsersSubscriptionsAsync(
tenantId,
notificationName,
sendToUsers);
return userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName));
}
catch(Exception ex)
{
Logger.LogWarning("Failed to get user subscription, message will not be received by the user, reason: {message}", ex.Message);
}
return new List<UserIdentifier>();
}
/// <summary>
/// 持久化通知并返回订阅用户列表
/// </summary>
/// <param name="notificationInfo">通知实体</param>
/// <param name="subscriptionUsers">订阅用户列表</param>
/// <param name="sendToProviders">通知发送提供者</param>
/// <returns>返回订阅者列表</returns>
protected async Task PersistentNotificationAsync(
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUsers,
IEnumerable<INotificationPublishProvider> sendToProviders)
{
try
{
// 持久化通知
await NotificationStore.InsertNotificationAsync(notificationInfo);
if (!subscriptionUsers.Any())
{
return;
}
// 持久化用户通知
await NotificationStore.InsertUserNotificationsAsync(notificationInfo, subscriptionUsers.Select(u => u.UserId));
if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne)
{
// 一次性通知取消用户订阅
await NotificationStore.DeleteUserSubscriptionAsync(
notificationInfo.TenantId,
subscriptionUsers,
notificationInfo.Name);
}
}
catch (Exception ex)
{
Logger.LogWarning("Failed to persistent notification failed, reason: {message}", ex.Message);
foreach (var provider in sendToProviders)
{
// 处理持久化失败进入后台队列
await ProcessingFailedToQueueAsync(provider, notificationInfo, subscriptionUsers);
}
}
}
/// <summary>
/// 发布订阅者通知
/// </summary>
/// <param name="provider">通知发布者</param>
/// <param name="notificationInfo">通知信息</param>
/// <param name="subscriptionUserIdentifiers">订阅用户列表</param>
/// <returns></returns>
protected async Task PublishToSubscriberAsync(
INotificationPublishProvider provider,
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUsers)
{
try
{
Logger.LogDebug($"Sending notification with provider {provider.Name}");
// 2024-10-10: 框架层面应该取消通知数据转换,而是交给提供商来实现
//var notifacationDataMapping = Options.NotificationDataMappings
// .GetMapItemOrDefault(provider.Name, notificationInfo.Name);
//if (notifacationDataMapping != null)
//{
// notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
//}
// 发布
await provider.PublishAsync(notificationInfo, subscriptionUsers);
Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
}
catch (Exception ex)
{
Logger.LogWarning($"Send notification error with provider {provider.Name}");
Logger.LogWarning($"Error message:{ex.Message}");
Logger.LogDebug($"Failed to send notification {notificationInfo.Name}. Try to push notification to background job");
// 发送失败的消息进入后台队列
await ProcessingFailedToQueueAsync(provider, notificationInfo, subscriptionUsers);
}
}
/// <summary>
/// 处理失败的消息进入后台队列
/// </summary>
/// <remarks>
/// 注: 如果入队失败,消息将被丢弃.
/// </remarks>
/// <param name="provider"></param>
/// <param name="notificationInfo"></param>
/// <param name="subscriptionUsers"></param>
/// <returns></returns>
protected async Task ProcessingFailedToQueueAsync(
INotificationPublishProvider provider,
NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUsers)
{
try
{
// 发送失败的消息进入后台队列
await BackgroundJobManager.EnqueueAsync(
new NotificationPublishJobArgs(
notificationInfo.GetId(),
provider.GetType().AssemblyQualifiedName,
subscriptionUsers.ToList(),
notificationInfo.TenantId));
}
catch(Exception ex)
{
Logger.LogWarning("Failed to push to background job, notification will be discarded, error cause: {message}", ex.Message);
}
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save