379 changed files with 27621 additions and 5465 deletions
File diff suppressed because it is too large
@ -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 框架的其他模块配合使用,以实现最佳效果。 |
|||
@ -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 框架的其他模块配合使用,以实现最佳效果。 |
|||
@ -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。 |
|||
@ -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" |
|||
} |
|||
} |
|||
] |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -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"); |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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 |
|||
``` |
|||
@ -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 |
|||
``` |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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(); |
|||
}); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"version": 1, |
|||
"isRoot": true, |
|||
"tools": { |
|||
"dotnet-ef": { |
|||
"version": "7.0.3", |
|||
"commands": [ |
|||
"dotnet-ef" |
|||
] |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
wwwroot |
|||
package*.json |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace LY.AIO.Applications.Single.Controllers; |
|||
|
|||
public class HomeController : Controller |
|||
{ |
|||
public IActionResult Index() |
|||
{ |
|||
return Redirect("/swagger"); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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"] |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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 }; |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -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(); ; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LY.AIO.Applications.Single.MultiTenancy; |
|||
|
|||
public interface ITenantConfigurationCache |
|||
{ |
|||
Task RefreshAsync(); |
|||
|
|||
Task<List<TenantConfiguration>> GetTenantsAsync(); |
|||
} |
|||
@ -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"; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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); |
|||
@ -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> |
|||
@ -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 |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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> |
|||
|
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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 |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
})); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
@page |
|||
@model LY.AIO.Applications.Single.Pages.Account.UseRecoveryCodeModel |
|||
@{ |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace LY.AIO.Applications.Single.Pages.Account |
|||
{ |
|||
public class UseRecoveryCodeModel : PageModel |
|||
{ |
|||
public void OnGet() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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> |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
|||
|
|||
namespace LY.AIO.Applications.Single.Pages |
|||
{ |
|||
public class IndexModel : AbpPageModel |
|||
{ |
|||
public void OnGet() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
@ -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(); |
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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))); |
|||
} |
|||
} |
|||
@ -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( |
|||
"感谢您的关注, 点击菜单了解更多."))); |
|||
} |
|||
} |
|||
@ -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, |
|||
}); |
|||
} |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
] |
|||
} |
|||
} |
|||
@ -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}" |
|||
} |
|||
} |
|||
] |
|||
} |
|||
} |
|||
@ -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(); |
|||
}; |
|||
@ -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> |
|||
@ -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\")" |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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,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 |
|||
@ -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 发布地址和密钥 |
|||
- 发布前建议进行完整测试 |
|||
@ -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,0 +1,12 @@ |
|||
{ |
|||
"version": 1, |
|||
"isRoot": true, |
|||
"tools": { |
|||
"dotnet-ef": { |
|||
"version": "7.0.3", |
|||
"commands": [ |
|||
"dotnet-ef" |
|||
] |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
wwwroot |
|||
package*.json |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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"); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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"] |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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…
Reference in new issue