From 9e9a41f9fce91e852d012b0db5f56c81c0fcc5ad Mon Sep 17 00:00:00 2001 From: feijie Date: Fri, 13 Dec 2024 21:14:59 +0800 Subject: [PATCH 01/29] =?UTF-8?q?=E2=9C=A8=20feat(README):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20LINGYUN.Abp.Aliyun=20=E5=92=8C=20LINGYUN.Abp.Tencen?= =?UTF-8?q?t=20=E6=A8=A1=E5=9D=97=E7=9A=84=E6=96=87=E6=A1=A3=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E4=B8=8E=E5=8A=9F=E8=83=BD=E6=A6=82=E8=BF=B0=E3=80=82?= =?UTF-8?q?=20=E2=9C=A8=20feat(README):=20=E6=96=B0=E5=A2=9E=20common=20?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=E5=9F=BA=E7=A1=80=E4=BB=8B=E7=BB=8D?= =?UTF-8?q?=E4=B8=8E=E5=8C=85=E5=90=AB=E9=A1=B9=E7=9B=AE=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aspnet-core/framework/cloud-aliyun/README.md | 33 +++++++++++ aspnet-core/framework/cloud-tencent/README.md | 42 +++++++++++++ aspnet-core/framework/common/README.md | 59 +++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 aspnet-core/framework/cloud-aliyun/README.md create mode 100644 aspnet-core/framework/cloud-tencent/README.md create mode 100644 aspnet-core/framework/common/README.md diff --git a/aspnet-core/framework/cloud-aliyun/README.md b/aspnet-core/framework/cloud-aliyun/README.md new file mode 100644 index 000000000..bd5216537 --- /dev/null +++ b/aspnet-core/framework/cloud-aliyun/README.md @@ -0,0 +1,33 @@ +# LINGYUN.Abp.Aliyun 模块概述 + +## 简介 +LINGYUN.Abp.Aliyun 模块集成了阿里云的 SDK,提供了对阿里云服务的全面支持,包括认证、短信服务和对象存储等功能。 + +## 包含的项目列表 +- **LINGYUN.Abp.Aliyun** +- **LINGYUN.Abp.Aliyun.Features** +- **LINGYUN.Abp.Aliyun.SettingManagement** + +## 每个项目的主要功能概述 + +### LINGYUN.Abp.Aliyun +- 提供阿里云服务的基础 SDK 集成。 +- 支持阿里云 RAM 认证和 STS Token 访问。 +- 支持短信服务和对象存储。 +- 提供分布式缓存支持。 + +### LINGYUN.Abp.Aliyun.Features +- 提供阿里云服务的功能定义和管理。 +- 支持启用/禁用阿里云服务功能。 +- 与 ABP 功能管理系统集成。 + +### LINGYUN.Abp.Aliyun.SettingManagement +- 提供阿里云服务配置的查询接口。 +- 通过 API 接口获取阿里云配置信息。 +- 与 ABP 设置管理系统集成。 + +## 模块的整体用途和重要性 +该模块为开发者提供了与阿里云服务的无缝集成,简化了云服务的使用和管理,提升了应用程序的灵活性和可扩展性。 + +## 如何使用或集成该模块 +在项目中引用相应的模块,并根据需要配置阿里云的相关参数。确保与 ABP 框架的其他模块配合使用,以实现最佳效果。 diff --git a/aspnet-core/framework/cloud-tencent/README.md b/aspnet-core/framework/cloud-tencent/README.md new file mode 100644 index 000000000..10b839f4b --- /dev/null +++ b/aspnet-core/framework/cloud-tencent/README.md @@ -0,0 +1,42 @@ +# LINGYUN.Abp.Tencent 模块概述 + +## 简介 +LINGYUN.Abp.Tencent 模块集成了腾讯云的各项服务,提供了对腾讯云服务的全面支持,包括对象存储、短信服务、QQ 互联和语音合成等功能。 + +## 包含的项目列表 +- **LINGYUN.Abp.Tencent** +- **LINGYUN.Abp.BlobStoring.Tencent** +- **LINGYUN.Abp.Sms.Tencent** +- **LINGYUN.Abp.Tencent.QQ** +- **LINGYUN.Abp.Tencent.SettingManagement** +- **LINGYUN.Abp.Tencent.TTS** + +## 每个项目的主要功能概述 + +### LINGYUN.Abp.Tencent +- 提供腾讯云 SDK 客户端工厂,支持动态创建腾讯云各项服务的客户端。 +- 支持多租户配置和多语言本地化。 +- 提供统一的腾讯云服务配置管理。 + +### LINGYUN.Abp.BlobStoring.Tencent +- 支持腾讯云对象存储服务,自动创建存储桶。 +- 支持多区域配置和文件大小限制。 + +### LINGYUN.Abp.Sms.Tencent +- 支持腾讯云短信服务的发送功能,支持多手机号批量发送。 +- 内置错误处理和日志记录。 + +### LINGYUN.Abp.Tencent.QQ +- 支持 QQ 互联快速登录,支持多租户配置。 + +### LINGYUN.Abp.Tencent.SettingManagement +- 提供腾讯云服务的配置管理界面,支持全局和租户级别的配置管理。 + +### LINGYUN.Abp.Tencent.TTS +- 支持腾讯云语音合成服务,提供 TTS 客户端工厂。 + +## 模块的整体用途和重要性 +该模块为开发者提供了与腾讯云服务的无缝集成,简化了云服务的使用和管理,提升了应用程序的灵活性和可扩展性。 + +## 如何使用或集成该模块 +在项目中引用相应的模块,并根据需要配置腾讯云的相关参数。确保与 ABP 框架的其他模块配合使用,以实现最佳效果。 diff --git a/aspnet-core/framework/common/README.md b/aspnet-core/framework/common/README.md new file mode 100644 index 000000000..bbb1c7e35 --- /dev/null +++ b/aspnet-core/framework/common/README.md @@ -0,0 +1,59 @@ +# common 模块概述 + +## 模块简介 +`common`模块是ABP框架的基础模块,提供了一系列通用功能和服务,旨在支持各种应用程序的开发和扩展。该模块包含多个子模块,每个子模块实现了特定的功能,帮助开发者快速构建高效的应用程序。 + +## 包含的项目列表 +1. **LINGYUN.Abp.Aliyun.Authorization** + - 提供阿里云基础认证功能,支持AppKeyId和AccessKeySecret的配置。 + +2. **LINGYUN.Abp.AspNetCore.HttpOverrides** + - 实现HTTP传输标头的重写,支持获取反向代理中的真实客户地址。 + +3. **LINGYUN.Abp.AspNetCore.Mvc.Client** + - 提供可配置的用户配置缓存时间,支持多租户接口。 + +4. **LINGYUN.Abp.BackgroundJobs.Hangfire** + - 基于Hangfire实现的后台作业模块,支持即时、延迟和周期性任务。 + +5. **LINGYUN.Abp.ExceptionHandling** + - 提供统一的异常处理和通知机制,支持自定义异常处理程序。 + +6. **LINGYUN.Abp.Location** + - 提供地理编码、反向地理编码和IP地理位置解析功能。 + +7. **LINGYUN.Abp.IdGenerator** + - 实现分布式唯一ID生成器,支持雪花算法。 + +8. **LINGYUN.Abp.Wrapper** + - 统一包装API返回结果和异常处理。 + +## 每个项目的主要功能概述 +- **阿里云认证模块**: 提供阿里云的认证功能,简化了对阿里云服务的访问。 +- **HTTP重写模块**: 处理HTTP请求中的标头,确保获取真实的客户端地址。 +- **MVC客户端模块**: 提供用户配置缓存,支持多租户架构。 +- **后台作业模块**: 支持任务的调度和执行,确保后台任务的可靠性。 +- **异常处理模块**: 处理应用中的异常,提供统一的通知机制。 +- **位置服务模块**: 提供地理位置相关的功能,支持地址与坐标之间的转换。 +- **ID生成模块**: 生成分布式唯一ID,确保在高并发环境下的唯一性。 +- **包装器模块**: 统一处理API的返回结果和异常,提升API的可用性。 + +## 模块的整体用途和重要性 +`common`模块为ABP框架提供了基础设施,支持开发者在构建应用时快速集成常用功能,减少重复工作,提高开发效率。通过这些模块,开发者能够更专注于业务逻辑的实现,而无需担心底层的实现细节。 + +## 如何使用或集成该模块的简要说明 +在项目中使用`common`模块时,只需在模块类中添加相应的依赖项,并在`ConfigureServices`方法中进行必要的配置。例如: + +```csharp +[DependsOn(typeof(LINGYUN.Abp.Aliyun.Authorization))] +public class YourProjectModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + // 配置服务 + } +} +``` + +## 提示 +本项目中的README是由AI模型分析代码逻辑后自动生成的,如有误,请提issues或PR。 From b5c990cf737aab0a14772401c0c66dd8e07a1a24 Mon Sep 17 00:00:00 2001 From: feijie Date: Fri, 13 Dec 2024 21:16:01 +0800 Subject: [PATCH 02/29] =?UTF-8?q?=F0=9F=93=9A=20docs:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E4=BD=93=E6=9C=8D=E5=8A=A1=E5=90=AF=E5=8A=A8=E6=8C=87?= =?UTF-8?q?=E5=8D=97=E6=96=87=E6=A1=A3=EF=BC=8C=E6=8F=90=E4=BE=9B=E8=AF=A6?= =?UTF-8?q?=E7=BB=86=E7=9A=84=E7=8E=AF=E5=A2=83=E9=85=8D=E7=BD=AE=E5=92=8C?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E5=88=9D=E5=A7=8B=E5=8C=96=E6=AD=A5?= =?UTF-8?q?=E9=AA=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LINGYUN.MicroService.SingleProject.sln | 5 +- .../appsettings.json | 3 +- .../SingleDbMigrationService.cs | 200 +++++----- docs/startup-aio-readme.en.md | 348 ++++++++++++++++++ docs/startup-aio-readme.md | 348 ++++++++++++++++++ 5 files changed, 801 insertions(+), 103 deletions(-) create mode 100644 docs/startup-aio-readme.en.md create mode 100644 docs/startup-aio-readme.md diff --git a/aspnet-core/LINGYUN.MicroService.SingleProject.sln b/aspnet-core/LINGYUN.MicroService.SingleProject.sln index 2f5af7160..219e3f2f7 100644 --- a/aspnet-core/LINGYUN.MicroService.SingleProject.sln +++ b/aspnet-core/LINGYUN.MicroService.SingleProject.sln @@ -428,6 +428,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\NuGet.Config = ..\NuGet.Config ..\README.en.md = ..\README.en.md ..\README.md = ..\README.md + ..\docs\startup-aio-readme.md = ..\docs\startup-aio-readme.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dapr", "dapr", "{FD9F5933-FDE5-4504-99BF-9050E0435C6D}" @@ -1288,10 +1289,10 @@ Global {F94E77C1-61E0-4FE8-9ECD-10A0102342E9}.Debug|Any CPU.Build.0 = Debug|Any CPU {F94E77C1-61E0-4FE8-9ECD-10A0102342E9}.Release|Any CPU.ActiveCfg = Release|Any CPU {F94E77C1-61E0-4FE8-9ECD-10A0102342E9}.Release|Any CPU.Build.0 = Release|Any CPU - {83D2F8F2-82C7-4919-9B65-D0FBF0B5324C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83D2F8F2-82C7-4919-9B65-D0FBF0B5324C}.Release|Any CPU.Build.0 = Release|Any CPU {83D2F8F2-82C7-4919-9B65-D0FBF0B5324C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83D2F8F2-82C7-4919-9B65-D0FBF0B5324C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83D2F8F2-82C7-4919-9B65-D0FBF0B5324C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83D2F8F2-82C7-4919-9B65-D0FBF0B5324C}.Release|Any CPU.Build.0 = Release|Any CPU {CAEF3248-527D-48B7-9C98-929AC573C381}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CAEF3248-527D-48B7-9C98-929AC573C381}.Debug|Any CPU.Build.0 = Debug|Any CPU {CAEF3248-527D-48B7-9C98-929AC573C381}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json index 2b17de592..daded80e0 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json @@ -3,7 +3,8 @@ "Kind": "Local" }, "ConnectionStrings": { - "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" + // "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//MySql + "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer"//PostgreSql }, "StringEncryption": { "DefaultPassPhrase": "s46c5q55nxpeS8Ra", diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleDbMigrationService.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleDbMigrationService.cs index a02a8e3aa..1247b3499 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleDbMigrationService.cs +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleDbMigrationService.cs @@ -1,101 +1,101 @@ -using LINGYUN.Abp.Saas.Tenants; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System; -using System.Linq; -using System.Threading.Tasks; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.DistributedLocking; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.Migrations; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Uow; - -namespace LY.MicroService.Applications.Single.EntityFrameworkCore; - -public class SingleDbMigrationService : EfCoreRuntimeDatabaseMigratorBase, 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>() - .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, 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>() + .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); + } } \ No newline at end of file diff --git a/docs/startup-aio-readme.en.md b/docs/startup-aio-readme.en.md new file mode 100644 index 000000000..baa9bb741 --- /dev/null +++ b/docs/startup-aio-readme.en.md @@ -0,0 +1,348 @@ +# Monolithic Service Startup Guide + +English | [简体中文](startup-aio-readme.md) + +## Table of Contents + +- [Requirements](#requirements) +- [Project Compilation](#project-compilation) +- [Environment Configuration](#environment-configuration) + - [Required Configuration](#required-configuration) + - [Optional Configuration](#optional-configuration) +- [Database Initialization](#database-initialization) +- [Service Startup](#service-startup) +- [Configuration Details](#configuration-details) + +## Requirements + +- .NET 8.0 SDK +- Database (support any of the following): + - PostgreSQL + - MySQL + - SQL Server (coming soon) +- Redis +- Docker (optional) + +## Project Compilation + +1. Ensure .NET 8.0 SDK is installed +2. Execute the following command in the project root directory to compile the entire project: + +```shell +./build/build-aspnetcore-release.ps1 +``` + +3. Open the `LY.MicroService.Applications.Single` solution in your IDE for debugging or publishing + +## Environment Configuration + +### Required Configuration + +#### 1. Database Configuration + +Multiple databases are supported. Here are configuration examples for each: + +##### PostgreSQL + +```shell +# Start PostgreSQL using Docker +docker run -d --name postgres \ + -p 5432:5432 \ + -e POSTGRES_PASSWORD=postgres \ + -e PGDATA=/var/lib/postgresql/data \ + postgres:latest +``` + +##### MySQL + +```shell +# Start MySQL using Docker +docker run -d --name mysql \ + -p 3306:3306 \ + -e MYSQL_ROOT_PASSWORD=mysql \ + mysql:latest +``` + +Create database: + +```sql +CREATE DATABASE `Platform-V70`; +``` + +##### SQL Server (coming soon) + +```shell +# Start SQL Server using Docker +docker run -d --name sqlserver \ + -p 1433:1433 \ + -e "ACCEPT_EULA=Y" \ + -e "SA_PASSWORD=yourStrong(!)Password" \ + mcr.microsoft.com/mssql/server:latest +``` + +#### 2. Configuration File Modification + +Modify the database connection strings in the following configuration files according to your chosen database: + +- `migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json` +- `LY.MicroService.Applications.Single/appsettings.Development.json` + +Database connection string examples: + +PostgreSQL: + +```json +{ + "ConnectionStrings": { + "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;" + } +} +``` + +MySQL: + +```json +{ + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" + } +} +``` + +SQL Server (coming soon): + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost,1433;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=True" + } +} +``` + +#### 3. Redis Service + +```shell +# Start Redis using Docker +docker run -d --name redis -p 6379:6379 redis:latest +``` + +Redis configuration example: + +```json +{ + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "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" + } + } + } +} +``` + +### Optional Configuration + +The following configurations are applicable for monolithic distributed architecture: + +#### 1. MinIO Distributed File Storage + +```json +{ + "Minio": { + "WithSSL": false, + "BucketName": "blobs", + "EndPoint": "127.0.0.1:19000", + "AccessKey": "{AccessKey}", + "SecretKey": "{SecretKey}", + "CreateBucketIfNotExists": false + } +} +``` + +#### 2. Elasticsearch Distributed Audit Logging + +```json +{ + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + } +} +``` + +## Database Initialization + +1. Run database migration script: + +Option 1 (Recommended): + +```shell +./aspnet-core/migrations/Migrate.ps1 +``` + +Follow the command line prompts to generate migration files and SQL scripts, then execute the SQL scripts to create database tables + +Option 2: +Taking PostgreSQL as an example: + +- Modify database connection information in `LY.MicroService.Applications.Single.DbMigrator/appsettings.PostgreSql.json` +- Navigate to `LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql` project +- Run `dotnet ef database update` +- Wait for migration completion + +2. Configure data initialization: + + - Modify database connection information in `LY.MicroService.Applications.Single.DbMigrator/appsettings.json` + - Ensure the correct database provider is selected + +3. Execute data migration: + - Run the `LY.MicroService.Applications.Single.DbMigrator` project + - Wait for migration to complete, basic table data will be initialized + +## Service Startup + +1. Run the `LY.MicroService.Applications.Single` project +2. Access Swagger API documentation in your browser: + - URL: http://127.0.0.1:30000/swagger + +## Configuration Details + +### 1. Basic Configuration + +#### Application Configuration + +```json +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001" + } +} +``` + +#### Distributed Cache Configuration + +```json +{ + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + } +} +``` + +### 2. Authentication Configuration + +#### OpenIddict Configuration + +```json +{ + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + } + }, + "Lifetime": { + "AccessToken": "14:00:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00" + } + } +} +``` + +#### Identity Authentication Configuration + +```json +{ + "Identity": { + "Password": { + "RequiredLength": 6, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + } +} +``` + +### 3. Feature Management Configuration + +```json +{ + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + } +} +``` + +### 4. Logging Configuration + +```json +{ + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning" + } + }, + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "rollingInterval": "Day" + } + } + ] + } +} +``` + +## Common Issues + +If you encounter problems, please check: + +1. Database connection string is correct +2. Correct database provider is selected +3. Redis connection is working +4. Required ports are not occupied +5. Database migration completed successfully +6. Authentication server configuration is correct +7. CORS configuration is correct (if frontend access has cross-origin issues) diff --git a/docs/startup-aio-readme.md b/docs/startup-aio-readme.md new file mode 100644 index 000000000..3f1feb0c9 --- /dev/null +++ b/docs/startup-aio-readme.md @@ -0,0 +1,348 @@ +# 单体服务启动指南 + +[English](startup-aio-readme.en.md) | 简体中文 + +## 目录 + +- [环境要求](#环境要求) +- [项目编译](#项目编译) +- [环境配置](#环境配置) + - [必选配置](#必选配置) + - [可选配置](#可选配置) +- [数据库初始化](#数据库初始化) +- [服务启动](#服务启动) +- [配置说明](#配置说明) + +## 环境要求 + +- .NET 8.0 SDK +- 数据库(支持以下任一种): + - PostgreSQL + - MySQL + - SQL Server(即将支持) +- Redis +- Docker(可选) + +## 项目编译 + +1. 确保已安装 .NET 8.0 SDK +2. 在项目根目录执行以下命令编译整个项目: + +```shell +./build/build-aspnetcore-release.ps1 +``` + +3. 使用 IDE 打开 `LY.MicroService.Applications.Single` 解决方案进行调试或发布 + +## 环境配置 + +### 必选配置 + +#### 1. 数据库配置 + +支持多种数据库,以下是各种数据库的配置示例: + +##### PostgreSQL + +```shell +# 使用Docker启动PostgreSQL +docker run -d --name postgres \ + -p 5432:5432 \ + -e POSTGRES_PASSWORD=postgres \ + -e PGDATA=/var/lib/postgresql/data \ + postgres:latest +``` + +##### MySQL + +```shell +# 使用Docker启动MySQL +docker run -d --name mysql \ + -p 3306:3306 \ + -e MYSQL_ROOT_PASSWORD=mysql \ + mysql:latest +``` + +创建数据库: + +```sql +CREATE DATABASE `Platform-V70`; +``` + +##### SQL Server(即将支持) + +```shell +# 使用Docker启动SQL Server +docker run -d --name sqlserver \ + -p 1433:1433 \ + -e "ACCEPT_EULA=Y" \ + -e "SA_PASSWORD=yourStrong(!)Password" \ + mcr.microsoft.com/mssql/server:latest +``` + +#### 2. 配置文件修改 + +需要根据选择的数据库类型修改以下配置文件中的数据库连接字符串: + +- `migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json` +- `LY.MicroService.Applications.Single/appsettings.Development.json` + +数据库连接字符串示例: + +PostgreSQL: + +```json +{ + "ConnectionStrings": { + "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;" + } +} +``` + +MySQL: + +```json +{ + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" + } +} +``` + +SQL Server(即将支持): + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost,1433;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=True" + } +} +``` + +#### 3. Redis 服务 + +```shell +# 使用Docker启动Redis +docker run -d --name redis -p 6379:6379 redis:latest +``` + +Redis 配置示例: + +```json +{ + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "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" + } + } + } +} +``` + +### 可选配置 + +以下配置适用于单体分布式架构: + +#### 1. MinIO 分布式文件存储 + +```json +{ + "Minio": { + "WithSSL": false, + "BucketName": "blobs", + "EndPoint": "127.0.0.1:19000", + "AccessKey": "{AccessKey}", + "SecretKey": "{SecretKey}", + "CreateBucketIfNotExists": false + } +} +``` + +#### 2. Elasticsearch 分布式审计日志 + +```json +{ + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + } +} +``` + +## 数据库初始化 + +1. 运行数据库迁移脚本: + +方案一(推荐): + +```shell +./aspnet-core/migrations/Migrate.ps1 +``` + +根据命令行提示生成迁移文件和 sql 脚本,然后执行 sql 脚本来创建数据表 + +方案二: +以 pgsql 为例 + +- 修改 `LY.MicroService.Applications.Single.DbMigrator/appsettings.PostgreSql.json` 中的数据库连接信息 +- 进入`LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql`项目 +- 运行 `dotnet ef database update` +- 等待数据迁移完成 + +2. 配置数据初始化: + + - 修改 `LY.MicroService.Applications.Single.DbMigrator/appsettings.json` 中的数据库连接信息 + - 确保选择了正确的数据库提供程序 + +3. 执行数据迁移: + - 运行 `LY.MicroService.Applications.Single.DbMigrator` 项目 + - 等待数据迁移完成,基础表数据将被初始化 + +## 服务启动 + +1. 运行 `LY.MicroService.Applications.Single` 项目 +2. 在浏览器中访问 Swagger 接口文档: + - URL: http://127.0.0.1:30000/swagger + +## 配置说明 + +### 1. 基础配置 + +#### 应用程序配置 + +```json +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001" + } +} +``` + +#### 分布式缓存配置 + +```json +{ + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + } +} +``` + +### 2. 认证配置 + +#### OpenIddict 配置 + +```json +{ + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + } + }, + "Lifetime": { + "AccessToken": "14:00:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00" + } + } +} +``` + +#### 身份认证配置 + +```json +{ + "Identity": { + "Password": { + "RequiredLength": 6, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + } +} +``` + +### 3. 功能开关配置 + +```json +{ + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + } +} +``` + +### 4. 日志配置 + +```json +{ + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning" + } + }, + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "rollingInterval": "Day" + } + } + ] + } +} +``` + +## 常见问题 + +如果遇到问题,请检查: + +1. 数据库连接字符串是否正确 +2. 是否选择了正确的数据库提供程序 +3. Redis 连接是否正常 +4. 必要的端口是否被占用 +5. 数据库迁移是否成功完成 +6. 认证服务器配置是否正确 +7. CORS 配置是否正确(如果前端访问出现跨域问题) From 4534bad4c901a9da20aa74c0c381ece75e9e5686 Mon Sep 17 00:00:00 2001 From: feijie Date: Fri, 13 Dec 2024 21:20:18 +0800 Subject: [PATCH 03/29] =?UTF-8?q?=F0=9F=93=9A=20docs(README):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=83=A8=E7=BD=B2=E9=80=89=E9=A1=B9=EF=BC=8C=E4=BB=8B?= =?UTF-8?q?=E7=BB=8D=E5=8D=95=E4=BD=93=E6=9C=8D=E5=8A=A1=E4=B8=8E=E5=BE=AE?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9A=84=E9=83=A8=E7=BD=B2=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 13 +++++++++++++ README.md | 13 ++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/README.en.md b/README.en.md index 74883c04b..fb79ea7d0 100644 --- a/README.en.md +++ b/README.en.md @@ -10,6 +10,19 @@ This is a [vue-vben-admin](https://github.com/anncwb/vue-vben-admin) -based Abp [![Build](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml/badge.svg)](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml) +## Deployment Options + +### Monolithic Service Deployment + +If you don't need a microservices architecture, you can choose the monolithic service deployment option. Monolithic services are characterized by simple deployment and easy maintenance. + +- [Monolithic Service Startup Guide](./docs/startup-aio-readme.en.md) +- [单体服务启动说明](./docs/startup-aio-readme.md) + +### Microservices Deployment + +If you need higher scalability and a more flexible service architecture, you can choose the microservices deployment option. + ## Quick Start ### 0、Configurate hosts diff --git a/README.md b/README.md index 9f0c91c39..dbcc172d0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - [English](./README.en.md) | 简体中文 [更新说明](./RELEASE.md) 更新说明 @@ -11,6 +10,18 @@ [![Build](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml/badge.svg)](https://github.com/colinin/abp-next-admin/actions/workflows/build.yml) +## 部署方案 + +### 单体服务部署 + +如果您不需要微服务架构,可以选择单体服务部署方案。单体服务具有部署简单、维护方便的特点。 + +- [单体服务启动说明](./docs/startup-aio-readme.md) +- [Monolithic Service Startup Guide](./docs/startup-aio-readme.en.md) + +### 微服务部署 + +如果您需要更高的可扩展性和更灵活的服务架构,可以选择微服务部署方案。 ## 快速搭建微服务启动项目 From 618e4d959995068392de299132f457fe8095b073 Mon Sep 17 00:00:00 2001 From: feijie Date: Sat, 14 Dec 2024 22:27:06 +0800 Subject: [PATCH 04/29] =?UTF-8?q?=F0=9F=8E=89=20feat(aspnet-core/migration?= =?UTF-8?q?s):=20=E6=96=B0=E5=A2=9E=20Entity=20Framework=20Core=20SQL=20Se?= =?UTF-8?q?rver=20=E6=A8=A1=E5=9D=97=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LINGYUN.MicroService.SingleProject.sln | 7 + ...vice.Applications.Single.DbMigrator.csproj | 1 + .../appsettings.SqlServer.json | 228 ++++++++++++++++++ ...ingle.EntityFrameworkCore.SqlServer.csproj | 16 ++ .../README.en.md | 59 +++++ .../README.md | 59 +++++ .../SingleMigrationsDbContextFactory.cs | 35 +++ ...tionsEntityFrameworkCoreSqlServerModule.cs | 26 ++ aspnet-core/migrations/Migrate.ps1 | 5 + aspnet-core/migrations/MigrateEn.ps1 | 5 + docs/startup-aio-readme.md | 4 +- 11 files changed, 443 insertions(+), 2 deletions(-) create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.SqlServer.json create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.en.md create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.md create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsDbContextFactory.cs create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsEntityFrameworkCoreSqlServerModule.cs diff --git a/aspnet-core/LINGYUN.MicroService.SingleProject.sln b/aspnet-core/LINGYUN.MicroService.SingleProject.sln index 219e3f2f7..3dde071c9 100644 --- a/aspnet-core/LINGYUN.MicroService.SingleProject.sln +++ b/aspnet-core/LINGYUN.MicroService.SingleProject.sln @@ -615,6 +615,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.Application EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.Applications.Single.EntityFrameworkCore.MySql", "migrations\LY.MicroService.Applications.Single.EntityFrameworkCore.MySql\LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.csproj", "{2B167D92-2327-4679-9096-49F274FABE0C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer", "migrations\LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer\LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj", "{30EEF879-CFF7-4661-89CB-9CB68328D008}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1613,6 +1615,10 @@ Global {2B167D92-2327-4679-9096-49F274FABE0C}.Debug|Any CPU.Build.0 = Debug|Any CPU {2B167D92-2327-4679-9096-49F274FABE0C}.Release|Any CPU.ActiveCfg = Release|Any CPU {2B167D92-2327-4679-9096-49F274FABE0C}.Release|Any CPU.Build.0 = Release|Any CPU + {30EEF879-CFF7-4661-89CB-9CB68328D008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30EEF879-CFF7-4661-89CB-9CB68328D008}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30EEF879-CFF7-4661-89CB-9CB68328D008}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30EEF879-CFF7-4661-89CB-9CB68328D008}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1909,6 +1915,7 @@ Global {AA742577-63B0-4188-AA36-AC6E0ED99BB6} = {07DFEB1E-ED92-4E97-A801-FAB2D70F4F35} {5A07FFDF-F979-44F9-BE24-81D6A25BEADB} = {0D69B63D-F082-4D57-9FF0-355642C56993} {2B167D92-2327-4679-9096-49F274FABE0C} = {0D69B63D-F082-4D57-9FF0-355642C56993} + {30EEF879-CFF7-4661-89CB-9CB68328D008} = {0D69B63D-F082-4D57-9FF0-355642C56993} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1} diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj index d2195682d..1f39486bc 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj @@ -59,6 +59,7 @@ + diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.SqlServer.json b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.SqlServer.json new file mode 100644 index 000000000..555dab9fb --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.SqlServer.json @@ -0,0 +1,228 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=True" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "SqlServer": { + "Enabled": true + } + } + }, + "Console": true, + "Http": true, + "Email": true, + "TemporalQuartz": true, + "JavaScriptActivities": true, + "UserTask": true, + "Conductor": true, + "Telnyx": true, + "BlobStoring": true, + "Emailing": true, + "Notification": true, + "Sms": true, + "IM": true, + "PublishWebhook": true, + "Webhooks": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "SqlServer": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "SqlServer": { + "Enabled": true + } + } + } + }, + "Server": { + "BaseUrl": "http://127.0.0.1:30000" + } + }, + "Quartz": { + "UsePersistentStore": false, + "Properties": { + "quartz.jobStore.dataSource": "tkm", + "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", + "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz", + "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;", + "quartz.dataSource.tkm.provider": "SqlServer", + "quartz.jobStore.clustered": "true", + "quartz.serializer.type": "json", + "quartz.dataSource.tkm.connectionStringName": "TaskManagement" + } + }, + "Redis": { + "IsEnabled": true, + "Configuration": "127.0.0.1,defaultDatabase=15", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "UseOpenIddict": true, + "Authority": "http://127.0.0.1:30001/", + "ApiName": "lingyun-abp-application", + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "IdentityServer": { + "Clients": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + }, + "Lifetime": { + "AuthorizationCode": "00:05:00", + "AccessToken": "14:00:00", + "DeviceCode": "00:10:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00", + "RefreshTokenReuseLeeway": "00:00:30", + "UserCode": "00:10:00" + } + }, + "Identity": { + "Password": { + "RequiredLength": 6, + "RequiredUniqueChars": 0, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + }, + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + }, + "TextTemplating": { + "IsDynamicStoreEnabled": true + }, + "WebhooksManagement": { + "IsDynamicStoreEnabled": true + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "abp.dev.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://127.0.0.1:9200", + "indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj new file mode 100644 index 000000000..8f0eab1d8 --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj @@ -0,0 +1,16 @@ + + + net8.0 + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.en.md b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.en.md new file mode 100644 index 000000000..06cf0b61a --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.en.md @@ -0,0 +1,59 @@ +# SQL Server Database Migration Guide + +This guide will help you manage SQL Server database migrations using the migration scripts. + +## Prerequisites + +1. Ensure .NET Core SDK is installed +2. Ensure Entity Framework Core tools are installed + ```powershell + dotnet tool install --global dotnet-ef + ``` +3. Ensure SQL Server connection string is properly configured + +## Usage Instructions + +### 1. Create New Migration + +1. Run the migration script in the `aspnet-core/migrations` directory: + ```powershell + # Use English version + .\MigrateEn.ps1 + + # Or use Chinese version + .\Migrate.ps1 + ``` + +2. Select SQL Server database context from the menu: + ``` + [3] LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer + ``` + +3. Enter migration name (optional): + - Press Enter to use default name: `AddNewMigration_yyyyMMdd_HHmmss` + - Or enter custom name, e.g.: `AddNewFeature` + +### 2. Generate SQL Script + +After creating the migration, the script will ask if you want to generate SQL script: + +1. Choose whether to generate SQL script (Y/N) +2. If Y is selected, following options will be available: + - `[A]` - Generate SQL script for all migrations + - `[L]` - Generate SQL script for latest migration only + - `[0-9]` - Generate from specified migration version + +Generated SQL scripts will be saved in: +``` +aspnet-core/InitSql/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/ +``` + +### 3. Apply Migration + +Generated SQL scripts can be applied to database through: + +1. Using SQL Server Management Studio or other SQL Server client tools to execute SQL script +2. Or using command line: + ```bash + sqlcmd -S your_server -d your_database -i your_script.sql + ``` diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.md b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.md new file mode 100644 index 000000000..e086b650a --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/README.md @@ -0,0 +1,59 @@ +# SQL Server 数据库迁移指南 + +本指南将帮助您使用迁移脚本来管理 SQL Server 数据库的迁移操作。 + +## 前置条件 + +1. 确保已安装 .NET Core SDK +2. 确保已安装 Entity Framework Core 工具 + ```powershell + dotnet tool install --global dotnet-ef + ``` +3. 确保已正确配置 SQL Server 连接字符串 + +## 使用说明 + +### 1. 创建新的迁移 + +1. 在 `aspnet-core/migrations` 目录下运行迁移脚本: + ```powershell + # 使用中文版本 + .\Migrate.ps1 + + # 或使用英文版本 + .\MigrateEn.ps1 + ``` + +2. 在菜单中选择 SQL Server 数据库上下文: + ``` + [3] LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer + ``` + +3. 输入迁移名称(可选): + - 直接回车将使用默认名称:`AddNewMigration_yyyyMMdd_HHmmss` + - 或输入自定义名称,如:`AddNewFeature` + +### 2. 生成 SQL 脚本 + +在创建迁移后,脚本会询问是否需要生成 SQL 脚本: + +1. 选择是否生成 SQL 脚本 (Y/N) +2. 如果选择 Y,将提供以下选项: + - `[A]` - 生成所有迁移的 SQL 脚本 + - `[L]` - 仅生成最新迁移的 SQL 脚本 + - `[0-9]` - 从指定的迁移版本开始生成 + +生成的 SQL 脚本将保存在: +``` +aspnet-core/InitSql/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/ +``` + +### 3. 应用迁移 + +生成的 SQL 脚本可以通过以下方式应用到数据库: + +1. 使用 SQL Server Management Studio 或其他 SQL Server 客户端工具执行 SQL 脚本 +2. 或使用命令行: + ```bash + sqlcmd -S your_server -d your_database -i your_script.sql + ``` diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsDbContextFactory.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsDbContextFactory.cs new file mode 100644 index 000000000..0d6919c93 --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsDbContextFactory.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using System; +using System.IO; + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer; + +public class SingleMigrationsDbContextFactory : IDesignTimeDbContextFactory +{ + public SingleMigrationsDbContext CreateDbContext(string[] args) + { + var configuration = BuildConfiguration(); + var connectionString = configuration.GetConnectionString("Default"); + + var builder = new DbContextOptionsBuilder() + .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(); + } +} diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsEntityFrameworkCoreSqlServerModule.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsEntityFrameworkCoreSqlServerModule.cs new file mode 100644 index 000000000..e08840d28 --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/SingleMigrationsEntityFrameworkCoreSqlServerModule.cs @@ -0,0 +1,26 @@ +using LINGYUN.Abp.Elsa.EntityFrameworkCore.SqlServer; +using Microsoft.Extensions.DependencyInjection; +using System; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Volo.Abp.Modularity; + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer; + +[DependsOn( + typeof(AbpEntityFrameworkCoreSqlServerModule), + typeof(AbpElsaEntityFrameworkCoreSqlServerModule), + typeof(SingleMigrationsEntityFrameworkCoreModule) + )] +public class SingleMigrationsEntityFrameworkCoreSqlServerModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAbpDbContext(); + + Configure(options => + { + options.UseSqlServer(); + }); + } +} diff --git a/aspnet-core/migrations/Migrate.ps1 b/aspnet-core/migrations/Migrate.ps1 index f52891443..3d6486b9b 100755 --- a/aspnet-core/migrations/Migrate.ps1 +++ b/aspnet-core/migrations/Migrate.ps1 @@ -21,6 +21,11 @@ $dbContexts = @{ Context = "SingleMigrationsDbContext" Factory = "SingleMigrationsDbContextFactory" } + “3” = @{ + Name = "LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer" + Context = "SingleMigrationsDbContext" + Factory = "SingleMigrationsDbContextFactory" + } } # 显示DbContext选择菜单 diff --git a/aspnet-core/migrations/MigrateEn.ps1 b/aspnet-core/migrations/MigrateEn.ps1 index 348910a43..3ae0df556 100644 --- a/aspnet-core/migrations/MigrateEn.ps1 +++ b/aspnet-core/migrations/MigrateEn.ps1 @@ -21,6 +21,11 @@ $dbContexts = @{ Context = "SingleMigrationsDbContext" Factory = "SingleMigrationsDbContextFactory" } + "3" = @{ + Name = "LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer" + Context = "SingleMigrationsDbContext" + Factory = "SingleMigrationsDbContextFactory" + } } # Display DbContext selection menu diff --git a/docs/startup-aio-readme.md b/docs/startup-aio-readme.md index 3f1feb0c9..605585796 100644 --- a/docs/startup-aio-readme.md +++ b/docs/startup-aio-readme.md @@ -69,7 +69,7 @@ docker run -d --name mysql \ CREATE DATABASE `Platform-V70`; ``` -##### SQL Server(即将支持) +##### SQL Server ```shell # 使用Docker启动SQL Server @@ -109,7 +109,7 @@ MySQL: } ``` -SQL Server(即将支持): +SQL Server: ```json { From aae7c90320a23d98c4df5dc70f793ce20e9815b2 Mon Sep 17 00:00:00 2001 From: feijie Date: Tue, 17 Dec 2024 22:27:54 +0800 Subject: [PATCH 05/29] =?UTF-8?q?=E2=9C=A8=20feat(AIO):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20LY.AIO.Applications.Single=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E4=BE=9D=E8=B5=96=E6=BA=90=E7=A0=81=E5=BC=95?= =?UTF-8?q?=E7=94=A8=EF=BC=8C=E5=8F=AF=E5=BF=AB=E8=BD=BB=E9=87=8F=E5=8C=96?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E6=95=B4=E5=A5=97=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LINGYUN.MicroService.SingleProject.sln | 7 + aspnet-core/services/Directory.Packages.props | 263 +++++ .../.config/dotnet-tools.json | 12 + .../LY.AIO.Applications.Single/.gitignore | 2 + .../AbpCookieAuthenticationHandler.cs | 89 ++ .../BackgroundJobs/NotificationPublishJob.cs | 38 + .../NotificationPublishJobArgs.cs | 22 + .../Controllers/HomeController.cs | 11 + .../Controllers/SettingMergeController.cs | 70 ++ .../Controllers/UserSettingMergeController.cs | 45 + .../LY.AIO.Applications.Single/Dockerfile | 19 + .../Distributed/ChatMessageEventHandler.cs | 59 ++ .../Distributed/NotificationEventHandler.cs | 470 +++++++++ .../Distributed/TenantSynchronizer.cs | 53 + .../Distributed/UserCreateEventHandler.cs | 30 + .../Distributed/WebhooksEventHandler.cs | 112 +++ .../Local/UserCreateJoinIMEventHandler.cs | 58 ++ .../UserCreateSendWelcomeEventHandler.cs | 69 ++ .../CustomIdentityResources.cs | 19 + .../LY.AIO.Applications.Single.csproj | 272 +++++ ...rviceApplicationsSingleModule.Configure.cs | 935 ++++++++++++++++++ .../MicroServiceApplicationsSingleModule.cs | 394 ++++++++ ...eSiteCookiesServiceCollectionExtensions.cs | 67 ++ .../MultiTenancy/ITenantConfigurationCache.cs | 10 + .../MultiTenancy/TenantConfigurationCache.cs | 59 ++ .../TenantConfigurationCacheItem.cs | 19 + .../PersonalInfo/Default.cshtml | 103 ++ .../PersonalInfo/Default.js | 28 + .../Pages/Account/EmailConfirm.cshtml | 17 + .../Pages/Account/EmailConfirm.cshtml.cs | 72 ++ .../Account/EmailConfirmConfirmation.cshtml | 13 + .../EmailConfirmConfirmation.cshtml.cs | 22 + .../Pages/Account/SendCode.cshtml | 26 + .../Pages/Account/SendCode.cshtml.cs | 125 +++ .../Pages/Account/SendEmailConfirm.cshtml | 16 + .../Pages/Account/SendEmailConfirm.cshtml.cs | 73 ++ .../Account/TwoFactorSupportedLoginModel.cs | 63 ++ .../Pages/Account/UseRecoveryCode.cshtml | 4 + .../Pages/Account/UseRecoveryCode.cshtml.cs | 11 + .../Account/VerifyAuthenticatorCode.cshtml | 26 + .../Account/VerifyAuthenticatorCode.cshtml.cs | 59 ++ .../Pages/Account/VerifyCode.cshtml | 29 + .../Pages/Account/VerifyCode.cshtml.cs | 90 ++ .../Pages/Index.cshtml | 36 + .../Pages/Index.cshtml.cs | 11 + .../Pages/_ViewImports.cshtml | 4 + .../LY.AIO.Applications.Single/Program.cs | 82 ++ .../Properties/launchSettings.json | 30 + .../TenantHeaderParamter.cs | 35 + .../Messages/TextMessageReplyContributor.cs | 21 + .../Messages/UserSubscribeEventContributor.cs | 21 + .../Messages/TextMessageReplyContributor.cs | 24 + .../appsettings.Development.json | 249 +++++ .../appsettings.PostgreSql.json | 246 +++++ .../appsettings.json | 89 ++ .../LY.AIO.Applications.Single/gulpfile.js | 10 + common.props | 2 +- 57 files changed, 4840 insertions(+), 1 deletion(-) create mode 100644 aspnet-core/services/Directory.Packages.props create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/.config/dotnet-tools.json create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/.gitignore create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Authentication/AbpCookieAuthenticationHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJob.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJobArgs.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Controllers/HomeController.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Controllers/SettingMergeController.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Controllers/UserSettingMergeController.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Dockerfile create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/ChatMessageEventHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/NotificationEventHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/UserCreateEventHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/WebhooksEventHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateJoinIMEventHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateSendWelcomeEventHandler.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/IdentityResources/CustomIdentityResources.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/ITenantConfigurationCache.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCache.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCacheItem.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/TwoFactorSupportedLoginModel.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Pages/_ViewImports.cshtml create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Program.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/Properties/launchSettings.json create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/TenantHeaderParamter.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/TextMessageReplyContributor.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/UserSubscribeEventContributor.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/WeChat/Work/Messages/TextMessageReplyContributor.cs create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/appsettings.json create mode 100644 aspnet-core/services/LY.AIO.Applications.Single/gulpfile.js diff --git a/aspnet-core/LINGYUN.MicroService.SingleProject.sln b/aspnet-core/LINGYUN.MicroService.SingleProject.sln index 3dde071c9..a850d1539 100644 --- a/aspnet-core/LINGYUN.MicroService.SingleProject.sln +++ b/aspnet-core/LINGYUN.MicroService.SingleProject.sln @@ -617,6 +617,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.Application EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer", "migrations\LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer\LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.csproj", "{30EEF879-CFF7-4661-89CB-9CB68328D008}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.AIO.Applications.Single", "services\LY.AIO.Applications.Single\LY.AIO.Applications.Single.csproj", "{37740138-D088-46F5-83A8-8A8180FE65D8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1619,6 +1621,10 @@ Global {30EEF879-CFF7-4661-89CB-9CB68328D008}.Debug|Any CPU.Build.0 = Debug|Any CPU {30EEF879-CFF7-4661-89CB-9CB68328D008}.Release|Any CPU.ActiveCfg = Release|Any CPU {30EEF879-CFF7-4661-89CB-9CB68328D008}.Release|Any CPU.Build.0 = Release|Any CPU + {37740138-D088-46F5-83A8-8A8180FE65D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37740138-D088-46F5-83A8-8A8180FE65D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37740138-D088-46F5-83A8-8A8180FE65D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37740138-D088-46F5-83A8-8A8180FE65D8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1916,6 +1922,7 @@ Global {5A07FFDF-F979-44F9-BE24-81D6A25BEADB} = {0D69B63D-F082-4D57-9FF0-355642C56993} {2B167D92-2327-4679-9096-49F274FABE0C} = {0D69B63D-F082-4D57-9FF0-355642C56993} {30EEF879-CFF7-4661-89CB-9CB68328D008} = {0D69B63D-F082-4D57-9FF0-355642C56993} + {37740138-D088-46F5-83A8-8A8180FE65D8} = {B4247B78-34BC-4A3F-91A4-661F7DCD6E10} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1} diff --git a/aspnet-core/services/Directory.Packages.props b/aspnet-core/services/Directory.Packages.props new file mode 100644 index 000000000..84f4c0737 --- /dev/null +++ b/aspnet-core/services/Directory.Packages.props @@ -0,0 +1,263 @@ + + + + 8.3.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/.config/dotnet-tools.json b/aspnet-core/services/LY.AIO.Applications.Single/.config/dotnet-tools.json new file mode 100644 index 000000000..6b93cca86 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "7.0.3", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/.gitignore b/aspnet-core/services/LY.AIO.Applications.Single/.gitignore new file mode 100644 index 000000000..7b6f60857 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/.gitignore @@ -0,0 +1,2 @@ +wwwroot +package*.json \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Authentication/AbpCookieAuthenticationHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/Authentication/AbpCookieAuthenticationHandler.cs new file mode 100644 index 000000000..2cf43e1f2 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Authentication/AbpCookieAuthenticationHandler.cs @@ -0,0 +1,89 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.Extensions.Options; +using System.Text.Encodings.Web; + +namespace LY.AIO.Applications.Single.Authentication; + +public class AbpCookieAuthenticationHandler : CookieAuthenticationHandler +{ + public AbpCookieAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder) : base(options, logger, encoder) + { + } + + public AbpCookieAuthenticationHandler( + IOptionsMonitor 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; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJob.cs b/aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJob.cs new file mode 100644 index 000000000..e1bbef7c2 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJob.cs @@ -0,0 +1,38 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Options; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; + +namespace LY.AIO.Applications.Single.BackgroundJobs; + +public class NotificationPublishJob : AsyncBackgroundJob, ITransientDependency +{ + protected AbpNotificationsPublishOptions Options { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } + protected INotificationDataSerializer NotificationDataSerializer { get; } + public NotificationPublishJob( + IOptions 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(); + var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); + notification.Data = NotificationDataSerializer.Serialize(notification.Data); + + await publishProvider.PublishAsync(notification, args.UserIdentifiers); + } + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJobArgs.cs b/aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJobArgs.cs new file mode 100644 index 000000000..8d721981c --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/BackgroundJobs/NotificationPublishJobArgs.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.Notifications; + +namespace LY.AIO.Applications.Single.BackgroundJobs; + +public class NotificationPublishJobArgs +{ + public Guid? TenantId { get; set; } + public long NotificationId { get; set; } + public string ProviderType { get; set; } + public List UserIdentifiers { get; set; } + public NotificationPublishJobArgs() + { + UserIdentifiers = new List(); + } + public NotificationPublishJobArgs(long id, string providerType, List userIdentifiers, Guid? tenantId = null) + { + NotificationId = id; + ProviderType = providerType; + UserIdentifiers = userIdentifiers; + TenantId = tenantId; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Controllers/HomeController.cs b/aspnet-core/services/LY.AIO.Applications.Single/Controllers/HomeController.cs new file mode 100644 index 000000000..c154b5098 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Controllers/HomeController.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; + +namespace LY.AIO.Applications.Single.Controllers; + +public class HomeController : Controller +{ + public IActionResult Index() + { + return Redirect("/swagger"); + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Controllers/SettingMergeController.cs b/aspnet-core/services/LY.AIO.Applications.Single/Controllers/SettingMergeController.cs new file mode 100644 index 000000000..dd64e4201 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Controllers/SettingMergeController.cs @@ -0,0 +1,70 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace LY.AIO.Applications.Single.Controllers; + +[ExposeServices( + typeof(SettingController), + typeof(SettingMergeController))] +public class SettingMergeController : SettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public SettingMergeController( + ISettingAppService settingAppService, + ISettingTestAppService settingTestAppService, + IOptions mergeOptions) + : base(settingAppService, settingTestAppService) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-tenant")] + public async override Task GetAllForCurrentTenantAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + 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 GetAllForGlobalAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForGlobalAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Controllers/UserSettingMergeController.cs b/aspnet-core/services/LY.AIO.Applications.Single/Controllers/UserSettingMergeController.cs new file mode 100644 index 000000000..ab8428491 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Controllers/UserSettingMergeController.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace LY.AIO.Applications.Single.Controllers; + +[ExposeServices( + typeof(UserSettingController), + typeof(UserSettingMergeController))] +public class UserSettingMergeController : UserSettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public UserSettingMergeController( + IUserSettingAppService service, + IOptions mergeOptions) + : base(service) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-user")] + public async override Task GetAllForCurrentUserAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(UserSettingMergeController), + }; + foreach (var serviceType in _mergeOptions.UserSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentUserAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Dockerfile b/aspnet-core/services/LY.AIO.Applications.Single/Dockerfile new file mode 100644 index 000000000..aee09fd66 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Dockerfile @@ -0,0 +1,19 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +LABEL maintainer="colin.in@foxmail.com" +WORKDIR /app + +COPY . /app + +#东8区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone + +EXPOSE 80/tcp +VOLUME [ "./app/blobs" ] +VOLUME [ "./app/Logs" ] +VOLUME [ "./app/Modules" ] + +RUN apt update +RUN apt install wget -y + +ENTRYPOINT ["dotnet", "LY.MicroService.Applications.Single.dll"] diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/ChatMessageEventHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/ChatMessageEventHandler.cs new file mode 100644 index 000000000..52cf0d875 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/ChatMessageEventHandler.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.IM; +using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.RealTime; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace LY.AIO.Applications.Single.EventBus.Distributed +{ + public class ChatMessageEventHandler : IDistributedEventHandler>, ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpIMOptions Options { get; } + + protected IMessageStore MessageStore { get; } + protected IMessageBlocker MessageBlocker { get; } + protected IMessageSenderProviderManager MessageSenderProviderManager { get; } + + public ChatMessageEventHandler( + IOptions options, + IMessageStore messageStore, + IMessageBlocker messageBlocker, + IMessageSenderProviderManager messageSenderProviderManager) + { + Options = options.Value; + MessageStore = messageStore; + MessageBlocker = messageBlocker; + MessageSenderProviderManager = messageSenderProviderManager; + + Logger = NullLogger.Instance; + } + + public async virtual Task HandleEventAsync(RealTimeEto 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); + } + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/NotificationEventHandler.cs new file mode 100644 index 000000000..275ba0a4d --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/NotificationEventHandler.cs @@ -0,0 +1,470 @@ +using LINGYUN.Abp.Notifications; +using LY.AIO.Applications.Single.BackgroundJobs; +using LY.AIO.Applications.Single.MultiTenancy; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System.Globalization; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Json; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.TextTemplating; +using Volo.Abp.Uow; + +namespace LY.AIO.Applications.Single.EventBus.Distributed +{ + /// + /// 订阅通知发布事件,统一发布消息 + /// + /// + /// 作用在于SignalR客户端只会与一台服务器建立连接, + /// 只有启用了SignlR服务端的才能真正将消息发布到客户端 + /// + public class NotificationEventHandler : + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpNotificationsPublishOptions Options { get; } + /// + /// Reference to . + /// + protected ICurrentTenant CurrentTenant { get; } + /// + /// Reference to . + /// + protected ITenantConfigurationCache TenantConfigurationCache { get; } + /// + /// Reference to . + /// + protected IJsonSerializer JsonSerializer { get; } + /// + /// Reference to . + /// + protected IBackgroundJobManager BackgroundJobManager { get; } + /// + /// Reference to . + /// + protected ITemplateRenderer TemplateRenderer { get; } + /// + /// Reference to . + /// + protected INotificationStore NotificationStore { get; } + /// + /// Reference to . + /// + protected IStringLocalizerFactory StringLocalizerFactory { get; } + /// + /// Reference to . + /// + protected INotificationDataSerializer NotificationDataSerializer { get; } + /// + /// Reference to . + /// + protected INotificationDefinitionManager NotificationDefinitionManager { get; } + /// + /// Reference to . + /// + protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } + /// + /// Reference to . + /// + protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } + + /// + /// Initializes a new instance of the class. + /// + public NotificationEventHandler( + ICurrentTenant currentTenant, + ITenantConfigurationCache tenantConfigurationCache, + IJsonSerializer jsonSerializer, + ITemplateRenderer templateRenderer, + IBackgroundJobManager backgroundJobManager, + IStringLocalizerFactory stringLocalizerFactory, + IOptions 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.Instance; + } + + [UnitOfWork] + public async virtual Task HandleEventAsync(NotificationEto 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 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 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 + { + // 模板不支持 $ 字符, 改为普通关键字 + { 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 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); + } + } + } + } + /// + /// 获取用户订阅列表 + /// + /// 通知名称 + /// 接收用户列表 + /// 租户标识 + /// 用户订阅列表 + protected async Task> GerSubscriptionUsersAsync( + string notificationName, + IEnumerable 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(); + } + /// + /// 持久化通知并返回订阅用户列表 + /// + /// 通知实体 + /// 订阅用户列表 + /// 通知发送提供者 + /// 返回订阅者列表 + protected async Task PersistentNotificationAsync( + NotificationInfo notificationInfo, + IEnumerable subscriptionUsers, + IEnumerable 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); + } + } + } + /// + /// 发布订阅者通知 + /// + /// 通知发布者 + /// 通知信息 + /// 订阅用户列表 + /// + protected async Task PublishToSubscriberAsync( + INotificationPublishProvider provider, + NotificationInfo notificationInfo, + IEnumerable 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); + } + } + /// + /// 处理失败的消息进入后台队列 + /// + /// + /// 注: 如果入队失败,消息将被丢弃. + /// + /// + /// + /// + /// + protected async Task ProcessingFailedToQueueAsync( + INotificationPublishProvider provider, + NotificationInfo notificationInfo, + IEnumerable 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); + } + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs new file mode 100644 index 000000000..7a33a9cae --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs @@ -0,0 +1,53 @@ +using LINGYUN.Abp.Saas.Tenants; +using LY.AIO.Applications.Single.MultiTenancy; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace LY.AIO.Applications.Single.EventBus.Distributed +{ + public class TenantSynchronizer : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler, + 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 eventData) + { + await TenantConfigurationCache.RefreshAsync(); + + await DataSeeder.SeedAsync(eventData.Entity.Id); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + + public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/UserCreateEventHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/UserCreateEventHandler.cs new file mode 100644 index 000000000..11684352e --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/UserCreateEventHandler.cs @@ -0,0 +1,30 @@ +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.EventBus.Local; +using Volo.Abp.Users; + +namespace LY.AIO.Applications.Single.EventBus.Distributed +{ + public class UserCreateEventHandler : IDistributedEventHandler>, ITransientDependency + { + private readonly ILocalEventBus _localEventBus; + public UserCreateEventHandler( + ILocalEventBus localEventBus) + { + _localEventBus = localEventBus; + } + /// + /// 接收添加用户事件,发布本地事件 + /// + /// + /// + public async Task HandleEventAsync(EntityCreatedEto eventData) + { + var localUserCreateEventData = new EntityCreatedEventData(eventData.Entity); + + await _localEventBus.PublishAsync(localUserCreateEventData); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/WebhooksEventHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/WebhooksEventHandler.cs new file mode 100644 index 000000000..3681560cb --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Distributed/WebhooksEventHandler.cs @@ -0,0 +1,112 @@ +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.Webhooks.EventBus; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; + +namespace LY.AIO.Applications.Single.EventBus.Distributed; + +public class WebhooksEventHandler : + IDistributedEventHandler, + 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 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 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; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateJoinIMEventHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateJoinIMEventHandler.cs new file mode 100644 index 000000000..822e1220d --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateJoinIMEventHandler.cs @@ -0,0 +1,58 @@ +using LINGYUN.Abp.MessageService.Chat; +using LINGYUN.Abp.MessageService.Notifications; +using LINGYUN.Abp.Notifications; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.Uow; +using Volo.Abp.Users; + +namespace LY.AIO.Applications.Single.EventBus.Local +{ + public class UserCreateJoinIMEventHandler : ILocalEventHandler>, ITransientDependency + { + private readonly IChatDataSeeder _chatDataSeeder; + private readonly INotificationSubscriptionManager _notificationSubscriptionManager; + public UserCreateJoinIMEventHandler( + IChatDataSeeder chatDataSeeder, + INotificationSubscriptionManager notificationSubscriptionManager) + { + _chatDataSeeder = chatDataSeeder; + _notificationSubscriptionManager = notificationSubscriptionManager; + } + /// + /// 接收添加用户事件,初始化IM用户种子 + /// + /// + /// + [UnitOfWork] + public async virtual Task HandleEventAsync(EntityCreatedEventData 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); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateSendWelcomeEventHandler.cs new file mode 100644 index 000000000..c430f94c0 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/EventBus/Local/UserCreateSendWelcomeEventHandler.cs @@ -0,0 +1,69 @@ +using LINGYUN.Abp.Notifications; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.Users; + +namespace LY.AIO.Applications.Single.EventBus.Local +{ + public class UserCreateSendWelcomeEventHandler : ILocalEventHandler>, ITransientDependency + { + private readonly INotificationSender _notificationSender; + private readonly INotificationSubscriptionManager _notificationSubscriptionManager; + public UserCreateSendWelcomeEventHandler( + INotificationSender notificationSender, + INotificationSubscriptionManager notificationSubscriptionManager + ) + { + _notificationSender = notificationSender; + _notificationSubscriptionManager = notificationSubscriptionManager; + } + + public async Task HandleEventAsync(EntityCreatedEventData 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 + { + { "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); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/IdentityResources/CustomIdentityResources.cs b/aspnet-core/services/LY.AIO.Applications.Single/IdentityResources/CustomIdentityResources.cs new file mode 100644 index 000000000..feefc80df --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/IdentityResources/CustomIdentityResources.cs @@ -0,0 +1,19 @@ +using LINGYUN.Abp.Identity; +using IdentityServer4.Models; + +namespace LY.AIO.Applications.Single.IdentityResources; + +public class CustomIdentityResources +{ + public class AvatarUrl : IdentityResource + { + public AvatarUrl() + { + Name = IdentityConsts.ClaimType.Avatar.Name; + DisplayName = IdentityConsts.ClaimType.Avatar.DisplayName; + Description = IdentityConsts.ClaimType.Avatar.Description; + Emphasize = true; + UserClaims = new string[] { IdentityConsts.ClaimType.Avatar.Name }; + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj new file mode 100644 index 000000000..d135a63ea --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj @@ -0,0 +1,272 @@ + + + + + + net8.0 + enable + LY.AIO.Applications.Single + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs new file mode 100644 index 000000000..f2f66239a --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs @@ -0,0 +1,935 @@ +using Elsa; +using Elsa.Options; +using LINGYUN.Abp.Aliyun.Localization; +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.DataProtectionManagement; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Exporter.MiniExcel; +using LINGYUN.Abp.Idempotent; +using LINGYUN.Abp.Identity.Session; +using LINGYUN.Abp.IdentityServer.IdentityResources; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Notifications; +using LINGYUN.Abp.OpenIddict.AspNetCore.Session; +using LINGYUN.Abp.OpenIddict.LinkUser; +using LINGYUN.Abp.OpenIddict.Permissions; +using LINGYUN.Abp.OpenIddict.Portal; +using LINGYUN.Abp.OpenIddict.Sms; +using LINGYUN.Abp.OpenIddict.WeChat; +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.Tencent.Localization; +using LINGYUN.Abp.TextTemplating; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Localization; +using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.Wrapper; +using LINGYUN.Platform.Localization; +using LY.AIO.Applications.Single.Authentication; +using LY.AIO.Applications.Single.IdentityResources; +using LY.AIO.Applications.Single.Microsoft.Extensions.DependencyInjection; +using LY.AIO.Applications.Single.WeChat.Official.Messages; +using Medallion.Threading; +using Medallion.Threading.Redis; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.IdentityModel.Logging; +using Microsoft.OpenApi.Models; +using MiniExcelLibs.Attributes; +using OpenIddict.Server; +using OpenIddict.Server.AspNetCore; +using Quartz; +using StackExchange.Redis; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text.Encodings.Web; +using System.Text.Unicode; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.AntiForgery; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.Auditing; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.BlobStoring; +using Volo.Abp.BlobStoring.FileSystem; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.FeatureManagement; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Http.Client; +using Volo.Abp.Identity.Localization; +using Volo.Abp.IdentityServer; +using Volo.Abp.IdentityServer.Localization; +using Volo.Abp.Json; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.OpenIddict; +using Volo.Abp.OpenIddict.Localization; +using Volo.Abp.PermissionManagement; +using Volo.Abp.Quartz; +using Volo.Abp.Security.Claims; +using Volo.Abp.SettingManagement; +using Volo.Abp.SettingManagement.Localization; +using Volo.Abp.Threading; +using Volo.Abp.UI.Navigation.Urls; +using Volo.Abp.VirtualFileSystem; +using VoloAbpExceptionHandlingOptions = Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingOptions; + +namespace LY.AIO.Applications.Single; + +public partial class MicroServiceApplicationsSingleModule +{ + protected const string DefaultCorsPolicyName = "Default"; + public static string ApplicationName { get; set; } = "MicroService-Applications-Single"; + private readonly static OneTimeRunner OneTimeRunner = new(); + + private void PreConfigureFeature() + { + OneTimeRunner.Run(() => + { + GlobalFeatureManager.Instance.Modules.Editions().EnableAll(); + }); + } + + private void PreConfigureApp(IConfiguration configuration) + { + AbpSerilogEnrichersConsts.ApplicationName = ApplicationName; + + PreConfigure(options => + { + // 以开放端口区别,应在0-31之间 + options.SnowflakeIdOptions.WorkerId = 1; + options.SnowflakeIdOptions.WorkerIdBits = 5; + options.SnowflakeIdOptions.DatacenterId = 1; + }); + + if (configuration.GetValue("App:ShowPii")) + { + IdentityModelEventSource.ShowPII = true; + } + } + + private void PreConfigureAuthServer(IConfiguration configuration) + { + PreConfigure(builder => + { + builder.AddValidation(options => + { + //options.AddAudiences("lingyun-abp-application"); + + options.UseLocalServer(); + + options.UseAspNetCore(); + + options.UseDataProtection(); + }); + }); + } + + private void PreConfigureIdentity() + { + PreConfigure(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("AuthServer:UseOpenIddict")) + { + PreConfigure(options => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(builder => + { + builder.AddSigningCertificate(certificate); + builder.AddEncryptionCertificate(certificate); + + builder.UseDataProtection(); + + // 禁用https + builder.UseAspNetCore() + .DisableTransportSecurityRequirement(); + }); + } + else + { + PreConfigure(options => + { + options.AddDeveloperSigningCredential = false; + }); + + PreConfigure(builder => + { + builder.AddSigningCredential(certificate); + }); + } + } + } + else + { + if (configuration.GetValue("AuthServer:UseOpenIddict")) + { + PreConfigure(options => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(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(options => + { + // 如果使用持久化存储, 则配置quartz持久层 + if (configuration.GetSection("Quartz:UsePersistentStore").Get()) + { + var settings = configuration.GetSection("Quartz:Properties").Get>(); + 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(elsa => + { + elsa + .AddActivitiesFrom() + .AddWorkflowsFrom() + .AddFeatures(startups, configuration) + .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)); + + elsa.DistributedLockingOptionsBuilder + .UseProviderFactory(sp => name => + { + var provider = sp.GetRequiredService(); + + return provider.CreateLock(name); + }); + }); + + services.AddNotificationHandlersFrom(); + + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(Elsa.Webhooks.Api.Endpoints.List).Assembly); + }); + } + + private void ConfigureAuthServer(IConfiguration configuration) + { + Configure(builder => + { + builder.DisableTransportSecurityRequirement(); + }); + + Configure(options => + { + options.DisableTransportSecurityRequirement = true; + }); + + Configure(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(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(options => + //{ + // options.EndpointConfigureActions.Add( + // (context) => + // { + // context.Endpoints.MapFallbackToPage("/_Host"); + // }); + //}); + var preActions = services.GetPreConfigureActions(); + + 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(options => + { + options.Limits.MaxRequestBodySize = null; + options.Limits.MaxRequestBufferSize = null; + }); + } + + private void ConfigureBlobStoring(IConfiguration configuration) + { + Configure(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(options => + { + options.NodeName = ApplicationName; + options.JobCleanEnabled = true; + options.JobFetchEnabled = true; + options.JobCheckEnabled = true; + }); + } + + private void ConfigureTextTemplating(IConfiguration configuration) + { + if (configuration.GetValue("TextTemplating:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicTemplateDefinitionStoreEnabled = true; + }); + } + } + + private void ConfigureFeatureManagement(IConfiguration configuration) + { + if (configuration.GetValue("FeatureManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicFeatureStoreEnabled = true; + }); + } + Configure(options => + { + options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = AbpSaasPermissions.Editions.ManageFeatures; + options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = AbpSaasPermissions.Tenants.ManageFeatures; + }); + } + + private void ConfigureSettingManagement(IConfiguration configuration) + { + if (configuration.GetValue("SettingManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicSettingStoreEnabled = true; + }); + } + } + + private void ConfigureWebhooksManagement(IConfiguration configuration) + { + if (configuration.GetValue("WebhooksManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicWebhookStoreEnabled = true; + }); + } + } + /// + /// 配置数据导出 + /// + private void ConfigureExporter() + { + Configure(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 }, + // }; + // }); + }); + } + /// + /// 配置数据权限 + /// + private void ConfigureEntityDataProtected() + { + // Configure(options => + // { + // options.AddEntities(typeof(DemoResource), + // new[] + // { + // typeof(Book), + // }); + // }); + } + + private void ConfigurePermissionManagement(IConfiguration configuration) + { + if (configuration.GetValue("PermissionManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicPermissionStoreEnabled = true; + }); + } + Configure(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("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("NotificationsManagement:IsDynamicStoreEnabled")) + { + Configure(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(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); + } + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LY.MicroService.Applications.Single"); + }); + } + + private void ConfigureIdempotent() + { + Configure(options => + { + options.IsEnabled = true; + options.DefaultTimeout = 0; + }); + } + + private void ConfigureDbContext() + { + Configure(options => + { + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + options.UseNpgsql(); + + // options.UseMySQL(); + }); + } + + private void ConfigureDataSeeder() + { + Configure(options => + { + options.Resources.Add(new CustomIdentityResources.AvatarUrl()); + }); + } + + private void ConfigureExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + // 未指定异常接收者的默认接收邮件 + // 指定自己的邮件地址 + }); + + Configure(options => + { + options.SendStackTraceToClients = false; + options.SendExceptionsDetailsToClients = false; + }); + } + + private void ConfigureJsonSerializer(IConfiguration configuration) + { + // 统一时间日期格式 + Configure(options => + { + var jsonConfiguration = configuration.GetSection("Json"); + if (jsonConfiguration.Exists()) + { + jsonConfiguration.Bind(options); + } + }); + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + configuration.GetSection("DistributedCache").Bind(options); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(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(); + }); + } + + private void ConfigureIdentity(IConfiguration configuration) + { + // 增加配置文件定义,在新建租户时需要 + Configure(options => + { + var identityConfiguration = configuration.GetSection("Identity"); + if (identityConfiguration.Exists()) + { + identityConfiguration.Bind(options); + } + }); + Configure(options => + { + options.IsDynamicClaimsEnabled = true; + }); + Configure(options => + { + options.IsCleanupEnabled = true; + }); + } + + private void ConfigureMvcUiTheme() + { + Configure(options => + { + //options.StyleBundles.Configure( + // LeptonXLiteThemeBundles.Styles.Global, + // bundle => + // { + // bundle.AddFiles("/global-styles.css"); + // } + //); + }); + } + + private void ConfigureLocalization() + { + Configure(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() + .AddBaseTypes( + typeof(IdentityResource), + typeof(AliyunResource), + typeof(TencentCloudResource), + typeof(WeChatResource), + typeof(PlatformResource), + typeof(AbpOpenIddictResource), + typeof(AbpIdentityServerResource)); + + options.UseAllPersistence(); + }); + + Configure(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(options => + { + options.IsEnabled = true; + // options.IsWrapUnauthorizedEnabled = true; + options.IgnoreNamespaces.Add("Elsa"); + }); + } + + private void PreConfigureWrapper() + { + //PreConfigure(options => + //{ + // options.ProxyRequestActions.Add( + // (appid, httprequestmessage) => + // { + // httprequestmessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + // }); + //}); + + PreConfigure(options => + { + options.ProxyClientActions.Add( + (_, _, client) => + { + client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + }); + }); + } + + private void ConfigureAuditing() + { + Configure(options => + { + // options.IsEnabledForGetRequests = true; + options.ApplicationName = ApplicationName; + }); + } + + private void ConfigureUrls(IConfiguration configuration) + { + Configure(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(options => + { + options.AutoValidate = false; + }); + + services.Replace(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(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>(); + }); + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs new file mode 100644 index 000000000..a0c2ce2d6 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs @@ -0,0 +1,394 @@ +using LINGYUN.Abp.Account; +using LINGYUN.Abp.Account.Templates; +using LINGYUN.Abp.Aliyun.SettingManagement; +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper; +using LINGYUN.Abp.AspNetCore.Mvc.Localization; +using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.Auditing; +using LINGYUN.Abp.AuditLogging.EntityFrameworkCore; +using LINGYUN.Abp.Authentication.QQ; +using LINGYUN.Abp.Authentication.WeChat; +using LINGYUN.Abp.Authorization.OrganizationUnits; +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.BackgroundTasks.Activities; +using LINGYUN.Abp.BackgroundTasks.DistributedLocking; +using LINGYUN.Abp.BackgroundTasks.EventBus; +using LINGYUN.Abp.BackgroundTasks.ExceptionHandling; +using LINGYUN.Abp.BackgroundTasks.Jobs; +using LINGYUN.Abp.BackgroundTasks.Notifications; +using LINGYUN.Abp.BackgroundTasks.Quartz; +using LINGYUN.Abp.CachingManagement; +using LINGYUN.Abp.CachingManagement.StackExchangeRedis; +using LINGYUN.Abp.Dapr.Client; +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.DataProtectionManagement; +using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore; +// using LINGYUN.Abp.Demo; +// using LINGYUN.Abp.Demo.EntityFrameworkCore; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Exporter.MiniExcel; +using LINGYUN.Abp.FeatureManagement; +using LINGYUN.Abp.FeatureManagement.HttpApi; +using LINGYUN.Abp.Features.LimitValidation; +using LINGYUN.Abp.Features.LimitValidation.Redis.Client; +using LINGYUN.Abp.Http.Client.Wrapper; +using LINGYUN.Abp.Identity; +using LINGYUN.Abp.Identity.AspNetCore.Session; +using LINGYUN.Abp.Identity.EntityFrameworkCore; +using LINGYUN.Abp.Identity.Notifications; +using LINGYUN.Abp.Identity.OrganizaztionUnits; +using LINGYUN.Abp.Identity.Session.AspNetCore; +using LINGYUN.Abp.Identity.WeChat; +using LINGYUN.Abp.IdGenerator; +using LINGYUN.Abp.IM.SignalR; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Localization.Persistence; +using LINGYUN.Abp.LocalizationManagement; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MessageService; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using LINGYUN.Abp.MultiTenancy.Editions; +using LINGYUN.Abp.Notifications; +using LINGYUN.Abp.Notifications.Common; +using LINGYUN.Abp.Notifications.Emailing; +using LINGYUN.Abp.Notifications.EntityFrameworkCore; +using LINGYUN.Abp.Notifications.SignalR; +using LINGYUN.Abp.Notifications.WeChat.MiniProgram; +using LINGYUN.Abp.OpenApi.Authorization; +using LINGYUN.Abp.OpenIddict; +using LINGYUN.Abp.OpenIddict.AspNetCore; +using LINGYUN.Abp.OpenIddict.AspNetCore.Session; +using LINGYUN.Abp.OpenIddict.Portal; +using LINGYUN.Abp.OpenIddict.Sms; +using LINGYUN.Abp.OpenIddict.WeChat; +using LINGYUN.Abp.OpenIddict.WeChat.Work; +using LINGYUN.Abp.OssManagement; +using LINGYUN.Abp.OssManagement.FileSystem; +// using LINGYUN.Abp.OssManagement.Imaging; +using LINGYUN.Abp.OssManagement.SettingManagement; +using LINGYUN.Abp.PermissionManagement; +using LINGYUN.Abp.PermissionManagement.HttpApi; +using LINGYUN.Abp.PermissionManagement.OrganizationUnits; +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.SettingManagement; +using LINGYUN.Abp.Sms.Aliyun; +using LINGYUN.Abp.TaskManagement; +using LINGYUN.Abp.TaskManagement.EntityFrameworkCore; +using LINGYUN.Abp.Tencent.QQ; +using LINGYUN.Abp.Tencent.SettingManagement; +using LINGYUN.Abp.TextTemplating; +using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; +using LINGYUN.Abp.UI.Navigation; +using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.Webhooks.EventBus; +using LINGYUN.Abp.Webhooks.Identity; +using LINGYUN.Abp.Webhooks.Saas; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; +using LINGYUN.Abp.WeChat.MiniProgram; +using LINGYUN.Abp.WeChat.Official; +using LINGYUN.Abp.WeChat.Official.Handlers; +using LINGYUN.Abp.WeChat.SettingManagement; +using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.WeChat.Work.Handlers; +using LINGYUN.Platform; +using LINGYUN.Platform.EntityFrameworkCore; +using LINGYUN.Platform.HttpApi; +using LINGYUN.Platform.Settings.VueVbenAdmin; +using LINGYUN.Platform.Theme.VueVbenAdmin; +using Volo.Abp; +using Volo.Abp.Account.Web; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore.PostgreSql; +using Volo.Abp.EventBus; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Imaging; +using Volo.Abp.Modularity; +using Volo.Abp.OpenIddict.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.Identity; +using Volo.Abp.PermissionManagement.OpenIddict; +using Volo.Abp.SettingManagement; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.Threading; +// using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql; +// using Volo.Abp.EntityFrameworkCore.MySQL; + +namespace LY.AIO.Applications.Single; + +[DependsOn( + typeof(AbpAccountApplicationModule), + typeof(AbpAccountHttpApiModule), + typeof(AbpAccountWebOpenIddictModule), + typeof(AbpAuditingApplicationModule), + typeof(AbpAuditingHttpApiModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule), + typeof(AbpCachingManagementStackExchangeRedisModule), + typeof(AbpCachingManagementApplicationModule), + typeof(AbpCachingManagementHttpApiModule), + typeof(AbpIdentityAspNetCoreSessionModule), + typeof(AbpIdentitySessionAspNetCoreModule), + typeof(AbpIdentityNotificationsModule), + typeof(AbpIdentityDomainModule), + typeof(AbpIdentityApplicationModule), + typeof(AbpIdentityHttpApiModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementDomainModule), + typeof(AbpLocalizationManagementApplicationModule), + typeof(AbpLocalizationManagementHttpApiModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpSerilogEnrichersApplicationModule), + typeof(AbpSerilogEnrichersUniqueIdModule), + typeof(AbpMessageServiceDomainModule), + typeof(AbpMessageServiceApplicationModule), + typeof(AbpMessageServiceHttpApiModule), + typeof(AbpMessageServiceEntityFrameworkCoreModule), + typeof(AbpNotificationsDomainModule), + typeof(AbpNotificationsApplicationModule), + typeof(AbpNotificationsHttpApiModule), + typeof(AbpNotificationsEntityFrameworkCoreModule), + + //typeof(AbpIdentityServerSessionModule), + //typeof(AbpIdentityServerApplicationModule), + //typeof(AbpIdentityServerHttpApiModule), + //typeof(AbpIdentityServerEntityFrameworkCoreModule), + + typeof(AbpOpenIddictAspNetCoreModule), + typeof(AbpOpenIddictAspNetCoreSessionModule), + typeof(AbpOpenIddictApplicationModule), + typeof(AbpOpenIddictHttpApiModule), + typeof(AbpOpenIddictEntityFrameworkCoreModule), + typeof(AbpOpenIddictSmsModule), + typeof(AbpOpenIddictPortalModule), + typeof(AbpOpenIddictWeChatModule), + typeof(AbpOpenIddictWeChatWorkModule), + + //typeof(AbpOssManagementMinioModule), // 取消注释以使用Minio + typeof(AbpOssManagementFileSystemModule), + // typeof(AbpOssManagementImagingModule), + typeof(AbpOssManagementDomainModule), + typeof(AbpOssManagementApplicationModule), + typeof(AbpOssManagementHttpApiModule), + typeof(AbpOssManagementSettingManagementModule), + typeof(AbpImagingImageSharpModule), + + typeof(PlatformDomainModule), + typeof(PlatformApplicationModule), + typeof(PlatformHttpApiModule), + typeof(PlatformEntityFrameworkCoreModule), + typeof(PlatformSettingsVueVbenAdminModule), + typeof(PlatformThemeVueVbenAdminModule), + typeof(AbpUINavigationVueVbenAdminModule), + + typeof(AbpSaasDomainModule), + typeof(AbpSaasApplicationModule), + typeof(AbpSaasHttpApiModule), + typeof(AbpSaasEntityFrameworkCoreModule), + + typeof(TaskManagementDomainModule), + typeof(TaskManagementApplicationModule), + typeof(TaskManagementHttpApiModule), + typeof(TaskManagementEntityFrameworkCoreModule), + + typeof(AbpTextTemplatingDomainModule), + typeof(AbpTextTemplatingApplicationModule), + typeof(AbpTextTemplatingHttpApiModule), + typeof(AbpTextTemplatingEntityFrameworkCoreModule), + + typeof(AbpWebhooksModule), + typeof(AbpWebhooksEventBusModule), + typeof(AbpWebhooksIdentityModule), + typeof(AbpWebhooksSaasModule), + typeof(WebhooksManagementDomainModule), + typeof(WebhooksManagementApplicationModule), + typeof(WebhooksManagementHttpApiModule), + typeof(WebhooksManagementEntityFrameworkCoreModule), + + typeof(AbpFeatureManagementApplicationModule), + typeof(AbpFeatureManagementHttpApiModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + + typeof(AbpSettingManagementDomainModule), + typeof(AbpSettingManagementApplicationModule), + typeof(AbpSettingManagementHttpApiModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + + typeof(AbpPermissionManagementApplicationModule), + typeof(AbpPermissionManagementHttpApiModule), + typeof(AbpPermissionManagementDomainIdentityModule), + typeof(AbpPermissionManagementDomainOpenIddictModule), + // typeof(AbpPermissionManagementDomainIdentityServerModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理 + + typeof(AbpEntityFrameworkCorePostgreSqlModule), + // typeof(AbpEntityFrameworkCoreMySQLModule), + + typeof(AbpAliyunSmsModule), + typeof(AbpAliyunSettingManagementModule), + + typeof(AbpAuthenticationQQModule), + typeof(AbpAuthenticationWeChatModule), + typeof(AbpAuthorizationOrganizationUnitsModule), + typeof(AbpIdentityOrganizaztionUnitsModule), + + typeof(AbpBackgroundTasksModule), + typeof(AbpBackgroundTasksActivitiesModule), + typeof(AbpBackgroundTasksDistributedLockingModule), + typeof(AbpBackgroundTasksEventBusModule), + typeof(AbpBackgroundTasksExceptionHandlingModule), + typeof(AbpBackgroundTasksJobsModule), + typeof(AbpBackgroundTasksNotificationsModule), + typeof(AbpBackgroundTasksQuartzModule), + + typeof(AbpDataProtectionManagementApplicationModule), + typeof(AbpDataProtectionManagementHttpApiModule), + typeof(AbpDataProtectionManagementEntityFrameworkCoreModule), + + // typeof(AbpDemoApplicationModule), + // typeof(AbpDemoHttpApiModule), + // typeof(AbpDemoEntityFrameworkCoreModule), + + typeof(AbpDaprClientModule), + typeof(AbpExceptionHandlingModule), + typeof(AbpEmailingExceptionHandlingModule), + typeof(AbpFeaturesLimitValidationModule), + typeof(AbpFeaturesValidationRedisClientModule), + typeof(AbpAspNetCoreMvcLocalizationModule), + + typeof(AbpLocalizationCultureMapModule), + typeof(AbpLocalizationPersistenceModule), + + typeof(AbpOpenApiAuthorizationModule), + + typeof(AbpIMSignalRModule), + + typeof(AbpNotificationsModule), + typeof(AbpNotificationsCommonModule), + typeof(AbpNotificationsSignalRModule), + typeof(AbpNotificationsEmailingModule), + typeof(AbpMultiTenancyEditionsModule), + + typeof(AbpTencentQQModule), + typeof(AbpTencentCloudSettingManagementModule), + + typeof(AbpIdentityWeChatModule), + typeof(AbpNotificationsWeChatMiniProgramModule), + typeof(AbpWeChatMiniProgramModule), + typeof(AbpWeChatOfficialModule), + typeof(AbpWeChatOfficialApplicationModule), + typeof(AbpWeChatOfficialHttpApiModule), + typeof(AbpWeChatWorkModule), + typeof(AbpWeChatWorkApplicationModule), + typeof(AbpWeChatWorkHttpApiModule), + typeof(AbpWeChatOfficialHandlersModule), + typeof(AbpWeChatWorkHandlersModule), + typeof(AbpWeChatSettingManagementModule), + + typeof(AbpDataDbMigratorModule), + typeof(AbpIdGeneratorModule), + typeof(AbpUINavigationModule), + typeof(AbpAccountTemplatesModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpCachingStackExchangeRedisModule), + // typeof(AbpElsaModule), + // typeof(AbpElsaServerModule), + // typeof(AbpElsaActivitiesModule), + // typeof(AbpElsaEntityFrameworkCoreModule), + // typeof(AbpElsaEntityFrameworkCorePostgreSqlModule), + // typeof(AbpElsaModule), + // typeof(AbpElsaServerModule), + // typeof(AbpElsaActivitiesModule), + // typeof(AbpElsaEntityFrameworkCoreModule), + // typeof(AbpElsaEntityFrameworkCoreMySqlModule), + + typeof(AbpExporterMiniExcelModule), + typeof(AbpAspNetCoreMvcUiMultiTenancyModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpHttpClientWrapperModule), + typeof(AbpAspNetCoreMvcWrapperModule), + typeof(AbpAspNetCoreMvcIdempotentWrapperModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpAspNetCoreMvcUiBasicThemeModule), + typeof(AbpEventBusModule), + typeof(AbpAutofacModule) + )] +public partial class MicroServiceApplicationsSingleModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + var hostingEnvironment = context.Services.GetHostingEnvironment(); + + PreConfigureWrapper(); + PreConfigureFeature(); + PreConfigureIdentity(); + PreConfigureApp(configuration); + PreConfigureQuartz(configuration); + PreConfigureAuthServer(configuration); + PreConfigureElsa(context.Services, configuration); + PreConfigureCertificate(configuration, hostingEnvironment); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + + ConfigureWeChat(); + ConfigureWrapper(); + ConfigureExporter(); + ConfigureAuditing(); + ConfigureDbContext(); + ConfigureIdempotent(); + ConfigureMvcUiTheme(); + ConfigureDataSeeder(); + ConfigureLocalization(); + ConfigureKestrelServer(); + ConfigureBackgroundTasks(); + ConfigureExceptionHandling(); + ConfigureVirtualFileSystem(); + ConfigureEntityDataProtected(); + ConfigureUrls(configuration); + ConfigureCaching(configuration); + ConfigureAuditing(configuration); + ConfigureIdentity(configuration); + ConfigureAuthServer(configuration); + ConfigureSwagger(context.Services); + ConfigureEndpoints(context.Services); + ConfigureBlobStoring(configuration); + ConfigureMultiTenancy(configuration); + ConfigureJsonSerializer(configuration); + ConfigureTextTemplating(configuration); + ConfigureFeatureManagement(configuration); + ConfigureSettingManagement(configuration); + ConfigureWebhooksManagement(configuration); + ConfigurePermissionManagement(configuration); + ConfigureNotificationManagement(configuration); + ConfigureCors(context.Services, configuration); + ConfigureDistributedLock(context.Services, configuration); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + AsyncHelper.RunSync(async () => await OnApplicationInitializationAsync(context)); + } + + public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + await context.ServiceProvider.GetRequiredService().SeedAsync(); ; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs b/aspnet-core/services/LY.AIO.Applications.Single/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs new file mode 100644 index 000000000..9413fb658 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs @@ -0,0 +1,67 @@ +namespace LY.AIO.Applications.Single.Microsoft.Extensions.DependencyInjection +{ + public static class SameSiteCookiesServiceCollectionExtensions + { + public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services) + { + services.Configure(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; + } + } +} \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/ITenantConfigurationCache.cs b/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/ITenantConfigurationCache.cs new file mode 100644 index 000000000..475466d04 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/ITenantConfigurationCache.cs @@ -0,0 +1,10 @@ +using Volo.Abp.MultiTenancy; + +namespace LY.AIO.Applications.Single.MultiTenancy; + +public interface ITenantConfigurationCache +{ + Task RefreshAsync(); + + Task> GetTenantsAsync(); +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCache.cs b/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCache.cs new file mode 100644 index 000000000..e6d81bdcc --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCache.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.Saas.Tenants; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace LY.AIO.Applications.Single.MultiTenancy; + +public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency +{ + protected ITenantRepository TenantRepository { get; } + protected IDistributedCache TenantCache { get; } + + public TenantConfigurationCache( + ITenantRepository tenantRepository, + IDistributedCache tenantCache) + { + TenantRepository = tenantRepository; + TenantCache = tenantCache; + } + + public async virtual Task RefreshAsync() + { + var cacheKey = GetCacheKey(); + + await TenantCache.RemoveAsync(cacheKey); + } + + public async virtual Task> GetTenantsAsync() + { + return (await GetForCacheItemAsync()).Tenants; + } + + protected async virtual Task 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"; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCacheItem.cs b/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCacheItem.cs new file mode 100644 index 000000000..023235e3e --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/MultiTenancy/TenantConfigurationCacheItem.cs @@ -0,0 +1,19 @@ +using Volo.Abp.MultiTenancy; + +namespace LY.AIO.Applications.Single.MultiTenancy; + +[IgnoreMultiTenancy] +public class TenantConfigurationCacheItem +{ + public List Tenants { get; set; } + + public TenantConfigurationCacheItem() + { + Tenants = new List(); + } + + public TenantConfigurationCacheItem(List tenants) + { + Tenants = tenants; + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml new file mode 100644 index 000000000..aed9202eb --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml @@ -0,0 +1,103 @@ +@using Volo.Abp.Account.Localization +@using Volo.Abp.Users +@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.Extensions.Localization +@using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using Volo.Abp.Data +@using Volo.Abp.Identity.Settings +@using Volo.Abp.Localization +@using Volo.Abp.Settings +@using Volo.Abp.ObjectExtending +@inject IHtmlLocalizer 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); +} + +

@L["PersonalSettings"]


+
+ + + + + + + + + + + + + + + + + + + + @if (CurrentUser.EmailVerified) + { + + } + else + { + @**@ + @L["Validation"].Value + } + + + + + + @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + { + 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); + } + + + } + else + { + + } + } + } + + + diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js new file mode 100644 index 000000000..55a88e52e --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js @@ -0,0 +1,28 @@ +(function ($) { + $(function () { + var l = abp.localization.getResource("AbpAccount"); + + $('#PersonalSettingsForm').submit(function (e) { + e.preventDefault(); + + if (!$('#PersonalSettingsForm').valid()) { + return false; + } + + var input = $('#PersonalSettingsForm').serializeFormToObject(); + + volo.abp.account.profile.update(input).then(function (result) { + abp.notify.success(l('PersonalSettingsSaved')); + updateConcurrencyStamp(); + }); + }); + }); + + abp.event.on('passwordChanged', updateConcurrencyStamp); + + function updateConcurrencyStamp(){ + volo.abp.account.profile.get().then(function(profile){ + $("#ConcurrencyStamp").val(profile.concurrencyStamp); + }); + } +})(jQuery); diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml new file mode 100644 index 000000000..63e834b2b --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml @@ -0,0 +1,17 @@ +@page +@inject IHtmlLocalizer 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 +
+
+

@L["EmailConfirm"]

+
+ + + @L["Cancel"] + + +
+
diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml.cs new file mode 100644 index 000000000..ea7b4671c --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirm.cshtml.cs @@ -0,0 +1,72 @@ +using LINGYUN.Abp.Account; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + public class EmailConfirmModel : AccountPageModel + { + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid UserId { get; set; } + + [Required] + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ConfirmToken { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrl { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrlHash { get; set; } + + public IMyProfileAppService MyProfileAppService { get; set; } + + public EmailConfirmModel() + { + LocalizationResourceType = typeof(AccountResource); + } + + public async virtual Task 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 + }); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml new file mode 100644 index 000000000..56c00aeaf --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml @@ -0,0 +1,13 @@ +@page +@model LY.AIO.Applications.Single.Pages.Account.EmailConfirmConfirmationModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@inject IHtmlLocalizer L +
+
+

@L["EmailConfirm"]

+

@L["YourEmailIsSuccessfullyConfirm"]

+ @L["GoToTheApplication"] +
+
diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml.cs new file mode 100644 index 000000000..a66f51c1b --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/EmailConfirmConfirmation.cshtml.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Account.Web.Pages.Account; + +namespace LY.AIO.Applications.Single.Pages.Account; + +[AllowAnonymous] +public class EmailConfirmConfirmationModel : AccountPageModel +{ + [BindProperty(SupportsGet = true)] + public string ReturnUrl { get; set; } + + [BindProperty(SupportsGet = true)] + public string ReturnUrlHash { get; set; } + + public async virtual Task OnGetAsync() + { + ReturnUrl = await GetRedirectUrlAsync(ReturnUrl, ReturnUrlHash); + + return Page(); + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml new file mode 100644 index 000000000..1598132ba --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml @@ -0,0 +1,26 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model LY.AIO.Applications.Single.Pages.Account.SendCodeModel +@inject IHtmlLocalizer L + +
+
+

@L["TwoFactor"]

+
+ + + +
+ +
+
+ @L["SendVerifyCode"] +
+ + @L["Login"] + + +
+
+ diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml.cs new file mode 100644 index 000000000..34b2f4c86 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendCode.cshtml.cs @@ -0,0 +1,125 @@ +using LINGYUN.Abp.Account.Emailing; +using LINGYUN.Abp.Identity.Settings; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Volo.Abp; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Sms; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + public class SendCodeModel : AccountPageModel + { + [BindProperty] + public SendCodeInputModel Input { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrl { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrlHash { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public bool RememberMe { get; set; } + + public IEnumerable 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 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 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; } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml new file mode 100644 index 000000000..68bc7890d --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml @@ -0,0 +1,16 @@ +@page +@inject IHtmlLocalizer 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 +
+
+

@L["EmailConfirm"]

+
+ + @L["Cancel"] + + +
+
diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml.cs new file mode 100644 index 000000000..c2ef4852f --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/SendEmailConfirm.cshtml.cs @@ -0,0 +1,73 @@ +using LINGYUN.Abp.Account; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + public class SendEmailConfirmModel : AccountPageModel + { + [BindProperty(SupportsGet = true)] + public string Email { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrl { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrlHash { get; set; } + + public IMyProfileAppService MyProfileAppService { get; set; } + + public SendEmailConfirmModel() + { + LocalizationResourceType = typeof(AccountResource); + } + + public virtual Task OnGetAsync() + { + Email = CurrentUser.Email; + + return Task.FromResult(Page()); + } + + public async virtual Task 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 + }); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/TwoFactorSupportedLoginModel.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/TwoFactorSupportedLoginModel.cs new file mode 100644 index 000000000..322cca6be --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/TwoFactorSupportedLoginModel.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.Account.Web; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.OpenIddict; +using IdentityOptions = Microsoft.AspNetCore.Identity.IdentityOptions; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + /// + /// 重写登录模型,实现双因素登录 + /// + [Dependency(ReplaceServices = true)] + [ExposeServices(typeof(LoginModel), typeof(OpenIddictSupportedLoginModel))] + public class TwoFactorSupportedLoginModel : OpenIddictSupportedLoginModel + { + public TwoFactorSupportedLoginModel( + IAuthenticationSchemeProvider schemeProvider, + IOptions accountOptions, + IOptions identityOptions, + IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache, + AbpOpenIddictRequestHelper openIddictRequestHelper) + : base(schemeProvider, accountOptions, identityOptions, identityDynamicClaimsPrincipalContributorCache, openIddictRequestHelper) + { + + } + + protected async override Task> 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 TwoFactorLoginResultAsync() + { + // 重定向双因素认证页面 + return Task.FromResult(RedirectToPage("SendCode", new + { + returnUrl = ReturnUrl, + returnUrlHash = ReturnUrlHash, + rememberMe = LoginInput.RememberMe + })); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml new file mode 100644 index 000000000..079925ee4 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml @@ -0,0 +1,4 @@ +@page +@model LY.AIO.Applications.Single.Pages.Account.UseRecoveryCodeModel +@{ +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml.cs new file mode 100644 index 000000000..016bf3771 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/UseRecoveryCode.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + public class UseRecoveryCodeModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml new file mode 100644 index 000000000..bc3e49acf --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml @@ -0,0 +1,26 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model LY.AIO.Applications.Single.Pages.Account.VerifyAuthenticatorCodeModel +@inject IHtmlLocalizer L +
+
+
+ + +
+ + + +
+
+ + +
+ @L["VerifyAuthenticatorCode"] + + @L["Login"] + +
+
+
\ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml.cs new file mode 100644 index 000000000..9a5d3c6ec --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyAuthenticatorCode.cshtml.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Web.Pages.Account; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + public class VerifyAuthenticatorCodeModel : AccountPageModel + { + [BindProperty] + public VerifyAuthenticatorCodeInputModel Input { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrl { get; set; } + + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string ReturnUrlHash { get; set; } + + [BindProperty(SupportsGet = true)] + public bool RememberBrowser { get; set; } + + [HiddenInput] + public bool RememberMe { get; set; } + + public virtual IActionResult OnGet() + { + Input = new VerifyAuthenticatorCodeInputModel(); + + return Page(); + } + + public virtual async Task 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; } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml new file mode 100644 index 000000000..94589fb71 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml @@ -0,0 +1,29 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model LY.AIO.Applications.Single.Pages.Account.VerifyCodeModel +
+
+
+ + + + +
+ +
+ + + + + +
+ @L["VerifyAuthenticatorCode"] +
+ + @L["ReSendVerifyCode"] + +
+
+
diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml.cs new file mode 100644 index 000000000..17ebff5bb --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Account/VerifyCode.cshtml.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; + +namespace LY.AIO.Applications.Single.Pages.Account +{ + public class VerifyCodeModel : AccountPageModel + { + [BindProperty] + public VerifyCodeInputModel Input { get; set; } + /// + /// ˫������֤�ṩ���� + /// + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string Provider { get; set; } + /// + /// �ض���Url + /// + [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 VerifyCodeModel() + { + LocalizationResourceType = typeof(AccountResource); + } + + public virtual IActionResult OnGet() + { + Input = new VerifyCodeInputModel(); + + return Page(); + } + + public virtual async Task 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 + { + /// + /// �Ƿ���������м�ס��¼״̬ + /// + public bool RememberBrowser { get; set; } + /// + /// ���͵���֤�� + /// + [Required] + public string VerifyCode { get; set; } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml new file mode 100644 index 000000000..f220a0b10 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml @@ -0,0 +1,36 @@ +@page +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Alert +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid +@using Volo.Abp.Users +@model LY.AIO.Applications.Single.Pages.IndexModel +@inject ICurrentUser CurrentUser +@if (CurrentUser.IsAuthenticated) +{ +
+ + + + Logout + + +

@CurrentUser.UserName

+
@CurrentUser.Email
+
+ Roles: @CurrentUser.Roles.JoinAsString(", ") +
+ Claims:
+ @Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString("
")) +
+
+
+
+} + +@if (!CurrentUser.IsAuthenticated) +{ +
+

+ Login +
+} \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml.cs b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml.cs new file mode 100644 index 000000000..5164786e9 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/Index.cshtml.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace LY.AIO.Applications.Single.Pages +{ + public class IndexModel : AbpPageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Pages/_ViewImports.cshtml b/aspnet-core/services/LY.AIO.Applications.Single/Pages/_ViewImports.cshtml new file mode 100644 index 000000000..c1da1f5f1 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling \ No newline at end of file diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Program.cs b/aspnet-core/services/LY.AIO.Applications.Single/Program.cs new file mode 100644 index 000000000..7d97a1b43 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Program.cs @@ -0,0 +1,82 @@ +using LINGYUN.Abp.Identity.Session.AspNetCore; +using LY.AIO.Applications.Single; +using Microsoft.AspNetCore.Cors; +using Serilog; +using Volo.Abp.IO; +using Volo.Abp.Modularity.PlugIns; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddCors(options => +{ + options.AddDefaultPolicy(policy => + { + policy + .WithOrigins( + builder.Configuration["App:CorsOrigins"] + .Split(",", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.RemovePostFix("/")) + .ToArray() + ) + .WithAbpExposedHeaders() + .WithAbpWrapExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); +}); +builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog((context, provider, config) => + { + config.ReadFrom.Configuration(context.Configuration); + }); + +await builder.AddApplicationAsync(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(); diff --git a/aspnet-core/services/LY.AIO.Applications.Single/Properties/launchSettings.json b/aspnet-core/services/LY.AIO.Applications.Single/Properties/launchSettings.json new file mode 100644 index 000000000..337677308 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:19139", + "sslPort": 0 + } + }, + "profiles": { + "LY.MicroService.Applications.Single": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://0.0.0.0:30001", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Production" + } + }, + "LY.MicroService.Applications.Single.Development": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://0.0.0.0:30000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/TenantHeaderParamter.cs b/aspnet-core/services/LY.AIO.Applications.Single/TenantHeaderParamter.cs new file mode 100644 index 000000000..9d80a45fd --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/TenantHeaderParamter.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.MultiTenancy; + +namespace LY.AIO.Applications.Single; + +public class TenantHeaderParamter : IOperationFilter +{ + private readonly AbpMultiTenancyOptions _multiTenancyOptions; + private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions; + public TenantHeaderParamter( + IOptions multiTenancyOptions, + IOptions aspNetCoreMultiTenancyOptions) + { + _multiTenancyOptions = multiTenancyOptions.Value; + _aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value; + } + + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (_multiTenancyOptions.IsEnabled) + { + operation.Parameters = operation.Parameters ?? new List(); + operation.Parameters.Add(new OpenApiParameter + { + Name = _aspNetCoreMultiTenancyOptions.TenantKey, + In = ParameterLocation.Header, + Description = "Tenant Id in http header", + Required = false + }); + } + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/TextMessageReplyContributor.cs b/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/TextMessageReplyContributor.cs new file mode 100644 index 000000000..593116275 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/TextMessageReplyContributor.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Official.Messages.Models; +using LINGYUN.Abp.WeChat.Official.Services; + +namespace LY.AIO.Applications.Single.WeChat.Official.Messages; +/// +/// 文本消息客服回复 +/// +public class TextMessageReplyContributor : IMessageHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + 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))); + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/UserSubscribeEventContributor.cs b/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/UserSubscribeEventContributor.cs new file mode 100644 index 000000000..249105de0 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Official/Messages/UserSubscribeEventContributor.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Official.Messages.Models; +using LINGYUN.Abp.WeChat.Official.Services; + +namespace LY.AIO.Applications.Single.WeChat.Official.Messages; +/// +/// 用户关注回复消息 +/// +public class UserSubscribeEventContributor : IEventHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + await messageSender.SendAsync( + new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel( + context.Message.FromUserName, + new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage( + "感谢您的关注, 点击菜单了解更多."))); + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Work/Messages/TextMessageReplyContributor.cs b/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Work/Messages/TextMessageReplyContributor.cs new file mode 100644 index 000000000..f0c6a2b1f --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/WeChat/Work/Messages/TextMessageReplyContributor.cs @@ -0,0 +1,24 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Work.Common.Messages.Models; +using LINGYUN.Abp.WeChat.Work.Messages; + +namespace LY.AIO.Applications.Single.WeChat.Work.Messages; +/// +/// 文本消息客服回复 +/// +public class TextMessageReplyContributor : IMessageHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + 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, + }); + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json new file mode 100644 index 000000000..a9d10fdff --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json @@ -0,0 +1,249 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { +// "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//Mysql + "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;"//Postgres + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "Console": true, + "Http": true, + "Email": true, + "TemporalQuartz": true, + "JavaScriptActivities": true, + "UserTask": true, + "Conductor": true, + "Telnyx": true, + "BlobStoring": true, + "Emailing": true, + "Notification": true, + "Sms": true, + "IM": true, + "PublishWebhook": true, + "Webhooks": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + } + }, + "Server": { + "BaseUrl": "http://127.0.0.1:30000" + } + }, + "Quartz": { + "UsePersistentStore": false, + "Properties": { + "quartz.jobStore.dataSource": "tkm", + "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz", + "quartz.dataSource.tkm.connectionStringName": "Default", +// "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz", +// "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456", +// "quartz.dataSource.tkm.provider": "MySqlConnector", + "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", + "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;", + "quartz.dataSource.tkm.provider": "Npgsql", + "quartz.jobStore.clustered": "true", + "quartz.serializer.type": "json" + } + }, + "Redis": { + "IsEnabled": true, + "Configuration": "127.0.0.1,defaultDatabase=15", + "InstanceName": "LINGYUN.Abp.Application" + }, + "Features": { + "Validation": { + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=13", + "InstanceName": "LINGYUN.Abp.Application" + } + } + }, + "AuthServer": { + "UseOpenIddict": true, + "Authority": "http://127.0.0.1:30001/", + "Audience": "lingyun-abp-application", + "RequireHttpsMetadata": false, + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "IdentityServer": { + "Clients": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + }, + "Lifetime": { + "AuthorizationCode": "00:05:00", + "AccessToken": "14:00:00", + "DeviceCode": "00:10:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00", + "RefreshTokenReuseLeeway": "00:00:30", + "UserCode": "00:10:00" + } + }, + "Identity": { + "Password": { + "RequiredLength": 6, + "RequiredUniqueChars": 0, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + }, + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + }, + "TextTemplating": { + "IsDynamicStoreEnabled": true + }, + "WebhooksManagement": { + "IsDynamicStoreEnabled": true + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "abp.dev.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + }, + "Minio": { + "WithSSL": false, + "BucketName": "blobs", + "EndPoint": "127.0.0.1:19000", + "AccessKey": "ZD43kNpimiJf9mCuomTP", + "SecretKey": "w8IqMgi4Tnz0DGzN8jZ7IJWq7OEdbUnAU0jlZxQK", + "CreateBucketIfNotExists": false + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://127.0.0.1:9200", + "indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json new file mode 100644 index 000000000..cf15e11f7 --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json @@ -0,0 +1,246 @@ +{ + "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": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": false, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "PostgreSql": { + "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": false, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "PostgreSql": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": false, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "PostgreSql": { + "Enabled": true + } + } + } + }, + "Server": { + "BaseUrl": "http://127.0.0.1:30000" + } + }, + "Quartz": { + "UsePersistentStore": false, + "Properties": { + "quartz.jobStore.dataSource": "tkm", + "quartz.jobStore.useProperties": "true", + "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz", + "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", + "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer", + "quartz.dataSource.tkm.provider": "Npgsql", + "quartz.dataSource.tkm.connectionStringName": "Default", + "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" + } + } + ] + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.json b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.json new file mode 100644 index 000000000..ff9beea3e --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.json @@ -0,0 +1,89 @@ +{ + "Clock": { + "Kind": "Local" + }, + "Forwarded": { + "ForwardedHeaders": "XForwardedFor,XForwardedProto" + }, + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Json": { + "OutputDateTimeFormat": "yyyy-MM-dd HH:mm:ss", + "InputDateTimeFormats": [ + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-ddTHH:mm:ss" + ] + }, + "AllowedHosts": "*", + "Hosting": { + "BasePath": "" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/services/LY.AIO.Applications.Single/gulpfile.js b/aspnet-core/services/LY.AIO.Applications.Single/gulpfile.js new file mode 100644 index 000000000..bec4d578f --- /dev/null +++ b/aspnet-core/services/LY.AIO.Applications.Single/gulpfile.js @@ -0,0 +1,10 @@ +"use strict"; + +var gulp = require("gulp"), + path = require('path'), + copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js'); + +exports.default = function(done){ + copyResources(path.resolve('./')); + done(); +}; \ No newline at end of file diff --git a/common.props b/common.props index cd370d567..9af819310 100644 --- a/common.props +++ b/common.props @@ -11,7 +11,7 @@ git https://github.com/colinin/abp-next-admin true - Debug;Release;PostgreSQL + Debug;Release From 1dac72a6bab425b67ded35f954742d01474d9cfc Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 18 Dec 2024 23:07:40 +0800 Subject: [PATCH 06/29] =?UTF-8?q?=F0=9F=94=A7=20=E4=BF=AE=E5=A4=8D(migrati?= =?UTF-8?q?ons):=20=E4=BF=AE=E6=94=B9=E4=BE=9D=E8=B5=96=E9=A1=B9=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81MySql=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SingleDbMigratorModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/SingleDbMigratorModule.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/SingleDbMigratorModule.cs index 4bce3b4fd..c42eeea3f 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/SingleDbMigratorModule.cs +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/SingleDbMigratorModule.cs @@ -1,7 +1,7 @@ using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; using Microsoft.Extensions.DependencyInjection; using LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql; -// using LY.MicroService.Applications.Single.EntityFrameworkCore.MySql; +using LY.MicroService.Applications.Single.EntityFrameworkCore.MySql; using Volo.Abp.Autofac; using Volo.Abp.Modularity; @@ -9,8 +9,8 @@ namespace LY.MicroService.Applications.Single.DbMigrator; [DependsOn( typeof(AbpUINavigationVueVbenAdminModule), - typeof(SingleMigrationsEntityFrameworkCorePostgreSqlModule), - // typeof(SingleMigrationsEntityFrameworkCoreMySqlModule), + // typeof(SingleMigrationsEntityFrameworkCorePostgreSqlModule), + typeof(SingleMigrationsEntityFrameworkCoreMySqlModule), typeof(AbpAutofacModule) )] public partial class SingleDbMigratorModule : AbpModule From 2b16f9a36bdb518b40ee0c5418866a3ba03338a1 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 18 Dec 2024 23:08:24 +0800 Subject: [PATCH 07/29] =?UTF-8?q?=F0=9F=9A=80=20feat(migrations):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84=E8=BF=81=E7=A7=BB=E4=BB=A5?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E8=AE=A4=E8=AF=81=E5=AE=9E=E4=BD=93=E5=8F=8A?= =?UTF-8?q?=E5=85=B6=E7=9B=B8=E5=85=B3=E5=B1=9E=E6=80=A7=E5=92=8C=E8=A7=84?= =?UTF-8?q?=E5=88=99=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...vice.Applications.Single.DbMigrator.csproj | 4 + .../appsettings.json | 4 +- ...ddNewMigration_20241218_225542.Designer.cs | 5828 +++++++++++++++++ ...8145610_AddNewMigration_20241218_225542.cs | 183 + .../SingleMigrationsDbContextModelSnapshot.cs | 289 + 5 files changed, 6306 insertions(+), 2 deletions(-) create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.Designer.cs create mode 100644 aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.cs diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj index 1f39486bc..5279f8ae4 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj @@ -35,6 +35,10 @@ PreserveNewest + + + PreserveNewest + diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json index daded80e0..4a3dae71a 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/appsettings.json @@ -3,8 +3,8 @@ "Kind": "Local" }, "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;SslMode=Prefer"//PostgreSql + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//MySql +// "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer"//PostgreSql }, "StringEncryption": { "DefaultPassPhrase": "s46c5q55nxpeS8Ra", diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.Designer.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.Designer.cs new file mode 100644 index 000000000..f61908182 --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.Designer.cs @@ -0,0 +1,5828 @@ +// +using System; +using LY.MicroService.Applications.Single.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migrations +{ + [DbContext(typeof(SingleMigrationsDbContext))] + [Migration("20241218145610_AddNewMigration_20241218_225542")] + partial class AddNewMigration_20241218_225542 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("TypeFullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("TypeFullName"); + + b.Property("TypeInfoId") + .HasColumnType("char(36)"); + + b.Property("ValueRange") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("ValueRange"); + + b.HasKey("Id"); + + b.HasIndex("TypeInfoId", "TypeFullName"); + + b.ToTable("AbpAuthEntityProperties", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsAuditEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("TypeFullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("TypeFullName"); + + b.HasKey("Id"); + + b.HasIndex("TypeFullName"); + + b.ToTable("AbpAuthEntitites", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowProperties") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("AllowProperties"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("EntityTypeFullName") + .HasColumnType("longtext"); + + b.Property("EntityTypeId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("FilterGroup") + .HasColumnType("longtext") + .HasColumnName("FilterGroup"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Operation") + .HasColumnType("int"); + + b.Property("OrgCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("OrgCode"); + + b.Property("OrgId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityTypeId"); + + b.ToTable("AbpAuthOrganizationUnitEntityRules", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowProperties") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("AllowProperties"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("EntityTypeFullName") + .HasColumnType("longtext"); + + b.Property("EntityTypeId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("FilterGroup") + .HasColumnType("longtext") + .HasColumnName("FilterGroup"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Operation") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("RoleName"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityTypeId"); + + b.ToTable("AbpAuthRoleEntityRules", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Demo.Authors.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BirthDate") + .HasColumnType("datetime(6)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ShortBio") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("Demo_Authors", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Demo.Books.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AuthorId") + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("Price") + .HasColumnType("float"); + + b.Property("PublishDate") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Demo_Books", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.LocalizationManagement.Language", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("CultureName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasColumnName("CultureName"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("DisplayName"); + + b.Property("Enable") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("TwoLetterISOLanguageName") + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("TwoLetterISOLanguageName"); + + b.Property("UiCultureName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasColumnName("UiCultureName"); + + b.HasKey("Id"); + + b.HasIndex("CultureName"); + + b.ToTable("AbpLocalizationLanguages", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.LocalizationManagement.Resource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DefaultCultureName") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("DefaultCultureName"); + + b.Property("Description") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Description"); + + b.Property("DisplayName") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("DisplayName"); + + b.Property("Enable") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasColumnName("Name"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpLocalizationResources", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.LocalizationManagement.Text", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CultureName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)") + .HasColumnName("CultureName"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("Key"); + + b.Property("ResourceName") + .HasColumnType("longtext"); + + b.Property("Value") + .HasMaxLength(2048) + .HasColumnType("varchar(2048)") + .HasColumnName("Value"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("AbpLocalizationTexts", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("AvatarUrl") + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("Birthday") + .HasColumnType("datetime(6)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Description") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LastOnlineTime") + .HasColumnType("datetime(6)"); + + b.Property("NickName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Sex") + .HasColumnType("int"); + + b.Property("Sign") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("State") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatCards", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Black") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Description") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("DontDisturb") + .HasColumnType("tinyint(1)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("FrientId") + .HasColumnType("char(36)"); + + b.Property("IsStatic") + .HasColumnType("tinyint(1)"); + + b.Property("RemarkName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("SpecialFocus") + .HasColumnType("tinyint(1)"); + + b.Property("Status") + .HasColumnType("tinyint unsigned"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "FrientId"); + + b.ToTable("AppUserChatFriends", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowAddFriend") + .HasColumnType("tinyint(1)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowReceiveMessage") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("RequireAddFriendValition") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatSettings", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("ReceiveUserId") + .HasColumnType("char(36)"); + + b.Property("SendUserName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("State") + .HasColumnType("tinyint"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ReceiveUserId"); + + b.ToTable("AppUserMessages", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.ChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("AdminUserId") + .HasColumnType("char(36)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("AvatarUrl") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Description") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("MaxUserCount") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)"); + + b.Property("Notice") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Tag") + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AppChatGroups", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupChatBlacks", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("longtext"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("SendUserName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("State") + .HasColumnType("tinyint"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupMessages", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId", "UserId"); + + b.ToTable("AppUserChatGroups", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserGroupCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsAdmin") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("NickName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("SilenceEnd") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserGroupCards", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Notifications.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentType") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("ExpirationTime") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("NotificationName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("NotificationTypeName") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("Severity") + .HasColumnType("tinyint"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "NotificationName"); + + b.ToTable("AppNotifications", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Notifications.NotificationDefinitionGroupRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowSubscriptionToClients") + .HasColumnType("tinyint(1)"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("DisplayName") + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.ToTable("AppNotificationDefinitionGroups", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Notifications.NotificationDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowSubscriptionToClients") + .HasColumnType("tinyint(1)"); + + b.Property("ContentType") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("DisplayName") + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("NotificationLifetime") + .HasColumnType("int"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.Property("Providers") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Template") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.HasKey("Id"); + + b.ToTable("AppNotificationDefinitions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Notifications.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("ReadStatus") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationId") + .HasDatabaseName("IX_Tenant_User_Notification_Id"); + + b.ToTable("AppUserNotifications", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Notifications.UserSubscribe", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("NotificationName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasDefaultValue("/"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationName") + .IsUnique() + .HasDatabaseName("IX_Tenant_User_Notification_Name"); + + b.ToTable("AppUserSubscribes", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Saas.Editions.Edition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.HasKey("Id"); + + b.HasIndex("DisplayName"); + + b.ToTable("AbpEditions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("DisableTime") + .HasColumnType("datetime(6)"); + + b.Property("EditionId") + .HasColumnType("char(36)"); + + b.Property("EnableTime") + .HasColumnType("datetime(6)"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("NormalizedName") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("EditionId"); + + b.HasIndex("Name"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpTenants", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("varchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("JobId") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("JobId"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("Name"); + + b.Property("Paramters") + .HasColumnType("longtext") + .HasColumnName("Paramters"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("TK_BackgroundJobActions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobInfo", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("Args") + .HasColumnType("longtext") + .HasColumnName("Args"); + + b.Property("BeginTime") + .HasColumnType("datetime(6)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Cron") + .HasMaxLength(50) + .HasColumnType("varchar(50)") + .HasColumnName("Cron"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Description"); + + b.Property("EndTime") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Group") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("Group"); + + b.Property("Interval") + .HasColumnType("int"); + + b.Property("IsAbandoned") + .HasColumnType("tinyint(1)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("JobType") + .HasColumnType("int"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LastRunTime") + .HasColumnType("datetime(6)"); + + b.Property("LockTimeOut") + .HasColumnType("int"); + + b.Property("MaxCount") + .HasColumnType("int"); + + b.Property("MaxTryCount") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("Name"); + + b.Property("NextRunTime") + .HasColumnType("datetime(6)"); + + b.Property("NodeName") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("NodeName"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("Result") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)") + .HasColumnName("Result"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("TriggerCount") + .HasColumnType("int"); + + b.Property("TryCount") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("varchar(1000)") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Name", "Group"); + + b.ToTable("TK_BackgroundJobs", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Exception") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)") + .HasColumnName("Exception"); + + b.Property("JobGroup") + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("JobGroup"); + + b.Property("JobId") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("JobId"); + + b.Property("JobName") + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("JobName"); + + b.Property("JobType") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)") + .HasColumnName("JobType"); + + b.Property("Message") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)") + .HasColumnName("Message"); + + b.Property("RunTime") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("JobGroup", "JobName"); + + b.ToTable("TK_BackgroundJobLogs", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.TextTemplating.TextTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Content") + .HasMaxLength(1048576) + .HasColumnType("longtext") + .HasColumnName("Content"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Culture") + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("Culture"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("DisplayName"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("Name"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .HasDatabaseName("IX_Tenant_Text_Template_Name"); + + b.ToTable("AbpTextTemplates", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.TextTemplating.TextTemplateDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("DefaultCultureName") + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("DefaultCultureName"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsInlineLocalized") + .HasColumnType("tinyint(1)"); + + b.Property("IsLayout") + .HasColumnType("tinyint(1)"); + + b.Property("IsStatic") + .HasColumnType("tinyint(1)"); + + b.Property("Layout") + .HasMaxLength(60) + .HasColumnType("varchar(60)") + .HasColumnName("Layout"); + + b.Property("LocalizationResourceName") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("LocalizationResourceName"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("Name"); + + b.Property("RenderEngine") + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("RenderEngine"); + + b.HasKey("Id"); + + b.ToTable("AbpTextTemplateDefinitions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("RequiredFeatures") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpWebhooksWebhooks", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("Data") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Data"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("WebhookName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("WebhookName"); + + b.HasKey("Id"); + + b.ToTable("AbpWebhooksEvents", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpWebhooksWebhookGroups", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("RequestHeaders") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("RequestHeaders"); + + b.Property("Response") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Response"); + + b.Property("ResponseHeaders") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("ResponseHeaders"); + + b.Property("ResponseStatusCode") + .HasColumnType("int"); + + b.Property("SendExactSameData") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("WebhookEventId") + .HasColumnType("char(36)"); + + b.Property("WebhookSubscriptionId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("WebhookEventId"); + + b.ToTable("AbpWebhooksSendAttempts", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Description") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("Description"); + + b.Property("Headers") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Headers"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Secret") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("Secret"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("TimeoutDuration") + .HasColumnType("int"); + + b.Property("WebhookUri") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("WebhookUri"); + + b.Property("Webhooks") + .HasMaxLength(2147483647) + .HasColumnType("longtext") + .HasColumnName("Webhooks"); + + b.HasKey("Id"); + + b.ToTable("AbpWebhooksSubscriptions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Datas.Data", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("varchar(1024)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)") + .HasColumnName("Description"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsStatic") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("Name"); + + b.Property("ParentId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AppPlatformDatas", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Datas.DataItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowBeNull") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DataId") + .HasColumnType("char(36)"); + + b.Property("DefaultValue") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DefaultValue"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)") + .HasColumnName("Description"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsStatic") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("Name"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DataId"); + + b.HasIndex("Name"); + + b.ToTable("AppPlatformDataItems", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Layouts.Layout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DataId") + .HasColumnType("char(36)"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Framework") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Framework"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("Path") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Path"); + + b.Property("Redirect") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Redirect"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("AppPlatformLayouts", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Menus.Menu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(23) + .HasColumnType("varchar(23)") + .HasColumnName("Code"); + + b.Property("Component") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Component"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Framework") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Framework"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPublic") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LayoutId") + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("ParentId") + .HasColumnType("char(36)"); + + b.Property("Path") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Path"); + + b.Property("Redirect") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Redirect"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("AppPlatformMenus", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Menus.RoleMenu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("MenuId") + .HasColumnType("char(36)"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("RoleName"); + + b.Property("Startup") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleName", "MenuId"); + + b.ToTable("AppPlatformRoleMenus", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Menus.UserFavoriteMenu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AliasName") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("AliasName"); + + b.Property("Color") + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("Framework") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Framework"); + + b.Property("Icon") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("Icon"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("MenuId") + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Path"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("UserId", "MenuId"); + + b.ToTable("AppPlatformUserFavoriteMenus", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Menus.UserMenu", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("MenuId") + .HasColumnType("char(36)"); + + b.Property("Startup") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("UserId", "MenuId"); + + b.ToTable("AppPlatformUserMenus", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Packages.Package", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Authors") + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("Authors"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Description"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("ForceUpdate") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Name"); + + b.Property("Note") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("varchar(1024)") + .HasColumnName("Note"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("Version"); + + b.HasKey("Id"); + + b.HasIndex("Name", "Version"); + + b.ToTable("AppPlatformPackages", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Packages.PackageBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Authors") + .HasMaxLength(100) + .HasColumnType("varchar(100)") + .HasColumnName("Authors"); + + b.Property("ContentType") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("ContentType"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DownloadCount") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("License") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)") + .HasColumnName("License"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Name"); + + b.Property("PackageId") + .HasColumnType("char(36)"); + + b.Property("SHA256") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("SHA256"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("Summary") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)") + .HasColumnName("Summary"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Url") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("Url"); + + b.HasKey("Id"); + + b.HasIndex("PackageId", "Name"); + + b.ToTable("AppPlatformPackageBlobs", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Platform.Portal.Enterprise", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Address") + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Address"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("EnglishName") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("EnglishName"); + + b.Property("ExpirationDate") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LegalMan") + .HasMaxLength(60) + .HasColumnType("varchar(60)") + .HasColumnName("LegalMan"); + + b.Property("Logo") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("Logo"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("varchar(255)") + .HasColumnName("Name"); + + b.Property("OrganizationCode") + .HasMaxLength(16) + .HasColumnType("varchar(16)") + .HasColumnName("OrganizationCode"); + + b.Property("RegistrationCode") + .HasMaxLength(30) + .HasColumnType("varchar(30)") + .HasColumnName("RegistrationCode"); + + b.Property("RegistrationDate") + .HasColumnType("datetime(6)"); + + b.Property("TaxCode") + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("TaxCode"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("AppPlatformEnterprises", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("varchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasColumnType("longtext"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("varchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("char(36)") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorTenantName") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("ImpersonatorTenantName"); + + b.Property("ImpersonatorUserId") + .HasColumnType("char(36)") + .HasColumnName("ImpersonatorUserId"); + + b.Property("ImpersonatorUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("ImpersonatorUserName"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("TenantName"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("char(36)") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AuditLogId") + .HasColumnType("char(36)") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime(6)") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AuditLogId") + .HasColumnType("char(36)") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime(6)") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint unsigned") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("char(36)"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EntityChangeId") + .HasColumnType("char(36)"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowedProviders") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("DefaultValue") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("IsAvailableToHost") + .HasColumnType("tinyint(1)"); + + b.Property("IsVisibleToClients") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ParentName") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ValueType") + .HasMaxLength(2048) + .HasColumnType("varchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpFeatures", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpFeatureGroups", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique(); + + b.ToTable("AbpFeatureValues", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("SourceTenantId") + .HasColumnType("char(36)"); + + b.Property("SourceUserId") + .HasColumnType("char(36)"); + + b.Property("TargetTenantId") + .HasColumnType("char(36)"); + + b.Property("TargetUserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique(); + + b.ToTable("AbpLinkUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("tinyint(1)") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("tinyint(1)") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("tinyint(1)") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("varchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("varchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("varchar(96)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime(6)"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)") + .HasColumnName("IsActive"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LastPasswordChangeTime") + .HasColumnType("datetime(6)"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("varchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("ShouldChangePasswordOnNextLogin") + .HasColumnType("tinyint(1)"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EndTime") + .HasColumnType("datetime(6)"); + + b.Property("SourceUserId") + .HasColumnType("char(36)"); + + b.Property("StartTime") + .HasColumnType("datetime(6)"); + + b.Property("TargetUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("AbpUserDelegations", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("varchar(196)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("varchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("char(36)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowedAccessTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.Property("ApiResourceId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("ApiResourceId", "Type"); + + b.ToTable("IdentityServerApiResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.Property("ApiResourceId") + .HasColumnType("char(36)"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.HasKey("ApiResourceId", "Key", "Value"); + + b.ToTable("IdentityServerApiResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.Property("ApiResourceId") + .HasColumnType("char(36)"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("ApiResourceId", "Scope"); + + b.ToTable("IdentityServerApiResourceScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.Property("ApiResourceId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)"); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.HasKey("ApiResourceId", "Type", "Value"); + + b.ToTable("IdentityServerApiResourceSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Emphasize") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.Property("ApiScopeId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("ApiScopeId", "Type"); + + b.ToTable("IdentityServerApiScopeClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.Property("ApiScopeId") + .HasColumnType("char(36)"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.HasKey("ApiScopeId", "Key", "Value"); + + b.ToTable("IdentityServerApiScopeProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("tinyint(1)"); + + b.Property("AllowOfflineAccess") + .HasColumnType("tinyint(1)"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("tinyint(1)"); + + b.Property("AllowRememberConsent") + .HasColumnType("tinyint(1)"); + + b.Property("AllowedIdentityTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("tinyint(1)"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("tinyint(1)"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("tinyint(1)"); + + b.Property("BackChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("ClientClaimsPrefix") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ClientName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ClientUri") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)"); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("tinyint(1)"); + + b.Property("FrontChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("tinyint(1)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("PairWiseSubjectSalt") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ProtocolType") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("tinyint(1)"); + + b.Property("RequireConsent") + .HasColumnType("tinyint(1)"); + + b.Property("RequirePkce") + .HasColumnType("tinyint(1)"); + + b.Property("RequireRequestObject") + .HasColumnType("tinyint(1)"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("tinyint(1)"); + + b.Property("UserCodeType") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("IdentityServerClients", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("Origin") + .HasMaxLength(150) + .HasColumnType("varchar(150)"); + + b.HasKey("ClientId", "Origin"); + + b.ToTable("IdentityServerClientCorsOrigins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("GrantType") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.HasKey("ClientId", "GrantType"); + + b.ToTable("IdentityServerClientGrantTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("Provider") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("ClientId", "Provider"); + + b.ToTable("IdentityServerClientIdPRestrictions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("PostLogoutRedirectUri") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.HasKey("ClientId", "PostLogoutRedirectUri"); + + b.ToTable("IdentityServerClientPostLogoutRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.HasKey("ClientId", "Key", "Value"); + + b.ToTable("IdentityServerClientProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("RedirectUri") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.HasKey("ClientId", "RedirectUri"); + + b.ToTable("IdentityServerClientRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("ClientId", "Scope"); + + b.ToTable("IdentityServerClientScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.Property("ClientId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Devices.DeviceFlowCodes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("varchar(10000)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("DeviceCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("UserCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.HasIndex("UserCode"); + + b.ToTable("IdentityServerDeviceFlowCodes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Grants.PersistedGrant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsumedTime") + .HasColumnType("datetime(6)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(10000) + .HasColumnType("varchar(10000)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Expiration") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Id") + .HasColumnType("char(36)"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.HasIndex("SubjectId", "SessionId", "Type"); + + b.ToTable("IdentityServerPersistedGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("varchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Emphasize") + .HasColumnType("tinyint(1)"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerIdentityResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.Property("IdentityResourceId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("IdentityResourceId", "Type"); + + b.ToTable("IdentityServerIdentityResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.Property("IdentityResourceId") + .HasColumnType("char(36)"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("varchar(250)"); + + b.Property("Value") + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.HasKey("IdentityResourceId", "Key", "Value"); + + b.ToTable("IdentityServerIdentityResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Applications.OpenIddictApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("ClientSecret") + .HasColumnType("longtext"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("ClientUri") + .HasColumnType("longtext"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .HasColumnType("longtext"); + + b.Property("DisplayNames") + .HasColumnType("longtext"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("JsonWebKeySet") + .HasColumnType("longtext"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasColumnType("longtext"); + + b.Property("Permissions") + .HasColumnType("longtext"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("longtext"); + + b.Property("Properties") + .HasColumnType("longtext"); + + b.Property("RedirectUris") + .HasColumnType("longtext"); + + b.Property("Requirements") + .HasColumnType("longtext"); + + b.Property("Settings") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Authorizations.OpenIddictAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ApplicationId") + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Properties") + .HasColumnType("longtext"); + + b.Property("Scopes") + .HasColumnType("longtext"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("varchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Scopes.OpenIddictScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Descriptions") + .HasColumnType("longtext"); + + b.Property("DisplayName") + .HasColumnType("longtext"); + + b.Property("DisplayNames") + .HasColumnType("longtext"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Properties") + .HasColumnType("longtext"); + + b.Property("Resources") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Tokens.OpenIddictToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ApplicationId") + .HasColumnType("char(36)"); + + b.Property("AuthorizationId") + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationDate") + .HasColumnType("datetime(6)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("char(36)") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime(6)") + .HasColumnName("DeletionTime"); + + b.Property("ExpirationDate") + .HasColumnType("datetime(6)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Payload") + .HasColumnType("longtext"); + + b.Property("Properties") + .HasColumnType("longtext"); + + b.Property("RedemptionDate") + .HasColumnType("datetime(6)"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("varchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("MultiTenancySide") + .HasColumnType("tinyint unsigned"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ParentName") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("Providers") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("StateCheckers") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpPermissions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique(); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpPermissionGroups", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("varchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique(); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.SettingDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DefaultValue") + .HasMaxLength(2048) + .HasColumnType("varchar(2048)"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsEncrypted") + .HasColumnType("tinyint(1)"); + + b.Property("IsInherited") + .HasColumnType("tinyint(1)"); + + b.Property("IsVisibleToClients") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("Providers") + .HasMaxLength(1024) + .HasColumnType("varchar(1024)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpSettingDefinitions", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b => + { + b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "TypeInfo") + .WithMany("Properties") + .HasForeignKey("TypeInfoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TypeInfo"); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b => + { + b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo") + .WithMany() + .HasForeignKey("EntityTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EntityTypeInfo"); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b => + { + b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo") + .WithMany() + .HasForeignKey("EntityTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EntityTypeInfo"); + }); + + modelBuilder.Entity("LINGYUN.Abp.Demo.Books.Book", b => + { + b.HasOne("LINGYUN.Abp.Demo.Authors.Author", null) + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b => + { + b.HasOne("LINGYUN.Abp.Saas.Editions.Edition", "Edition") + .WithMany() + .HasForeignKey("EditionId"); + + b.Navigation("Edition"); + }); + + modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.TenantConnectionString", b => + { + b.HasOne("LINGYUN.Abp.Saas.Tenants.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b => + { + b.HasOne("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", "WebhookEvent") + .WithOne() + .HasForeignKey("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", "WebhookEventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("WebhookEvent"); + }); + + modelBuilder.Entity("LINGYUN.Platform.Datas.DataItem", b => + { + b.HasOne("LINGYUN.Platform.Datas.Data", null) + .WithMany("Items") + .HasForeignKey("DataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("LINGYUN.Platform.Packages.PackageBlob", b => + { + b.HasOne("LINGYUN.Platform.Packages.Package", "Package") + .WithMany("Blobs") + .HasForeignKey("PackageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("Properties") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Authorizations.OpenIddictAuthorization", b => + { + b.HasOne("Volo.Abp.OpenIddict.Applications.OpenIddictApplication", null) + .WithMany() + .HasForeignKey("ApplicationId"); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Tokens.OpenIddictToken", b => + { + b.HasOne("Volo.Abp.OpenIddict.Applications.OpenIddictApplication", null) + .WithMany() + .HasForeignKey("ApplicationId"); + + b.HasOne("Volo.Abp.OpenIddict.Authorizations.OpenIddictAuthorization", null) + .WithMany() + .HasForeignKey("AuthorizationId"); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b => + { + b.Navigation("Properties"); + }); + + modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); + + modelBuilder.Entity("LINGYUN.Platform.Datas.Data", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("LINGYUN.Platform.Packages.Package", b => + { + b.Navigation("Blobs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Navigation("Properties"); + + b.Navigation("Scopes"); + + b.Navigation("Secrets"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Navigation("AllowedCorsOrigins"); + + b.Navigation("AllowedGrantTypes"); + + b.Navigation("AllowedScopes"); + + b.Navigation("Claims"); + + b.Navigation("ClientSecrets"); + + b.Navigation("IdentityProviderRestrictions"); + + b.Navigation("PostLogoutRedirectUris"); + + b.Navigation("Properties"); + + b.Navigation("RedirectUris"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.cs new file mode 100644 index 000000000..e93c422e8 --- /dev/null +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20241218145610_AddNewMigration_20241218_225542.cs @@ -0,0 +1,183 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migrations +{ + /// + public partial class AddNewMigration_20241218_225542 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AbpAuthEntitites", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Name = table.Column(type: "varchar(64)", maxLength: 64, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DisplayName = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + TypeFullName = table.Column(type: "varchar(256)", maxLength: 256, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IsAuditEnabled = table.Column(type: "tinyint(1)", nullable: false), + ExtraProperties = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ConcurrencyStamp = table.Column(type: "varchar(40)", maxLength: 40, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + CreatorId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + LastModificationTime = table.Column(type: "datetime(6)", nullable: true), + LastModifierId = table.Column(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(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Name = table.Column(type: "varchar(64)", maxLength: 64, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DisplayName = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + TypeFullName = table.Column(type: "varchar(256)", maxLength: 256, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ValueRange = table.Column(type: "varchar(512)", maxLength: 512, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + TypeInfoId = table.Column(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(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + OrgId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + OrgCode = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ExtraProperties = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ConcurrencyStamp = table.Column(type: "varchar(40)", maxLength: 40, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + CreatorId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + LastModificationTime = table.Column(type: "datetime(6)", nullable: true), + LastModifierId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + IsEnabled = table.Column(type: "tinyint(1)", nullable: false), + Operation = table.Column(type: "int", nullable: false), + FilterGroup = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + EntityTypeId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + EntityTypeFullName = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + AllowProperties = table.Column(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(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + RoleId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + RoleName = table.Column(type: "varchar(256)", maxLength: 256, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ExtraProperties = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ConcurrencyStamp = table.Column(type: "varchar(40)", maxLength: 40, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + CreatorId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + LastModificationTime = table.Column(type: "datetime(6)", nullable: true), + LastModifierId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + IsEnabled = table.Column(type: "tinyint(1)", nullable: false), + Operation = table.Column(type: "int", nullable: false), + FilterGroup = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + EntityTypeId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + EntityTypeFullName = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + AllowProperties = table.Column(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"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AbpAuthEntityProperties"); + + migrationBuilder.DropTable( + name: "AbpAuthOrganizationUnitEntityRules"); + + migrationBuilder.DropTable( + name: "AbpAuthRoleEntityRules"); + + migrationBuilder.DropTable( + name: "AbpAuthEntitites"); + } + } +} diff --git a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs index 323306a7d..59856a89b 100644 --- a/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs +++ b/aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs @@ -24,6 +24,257 @@ protected override void BuildModel(ModelBuilder modelBuilder) MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("TypeFullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("TypeFullName"); + + b.Property("TypeInfoId") + .HasColumnType("char(36)"); + + b.Property("ValueRange") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("ValueRange"); + + b.HasKey("Id"); + + b.HasIndex("TypeInfoId", "TypeFullName"); + + b.ToTable("AbpAuthEntityProperties", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("IsAuditEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Name"); + + b.Property("TypeFullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("TypeFullName"); + + b.HasKey("Id"); + + b.HasIndex("TypeFullName"); + + b.ToTable("AbpAuthEntitites", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowProperties") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("AllowProperties"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("EntityTypeFullName") + .HasColumnType("longtext"); + + b.Property("EntityTypeId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("FilterGroup") + .HasColumnType("longtext") + .HasColumnName("FilterGroup"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Operation") + .HasColumnType("int"); + + b.Property("OrgCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)") + .HasColumnName("OrgCode"); + + b.Property("OrgId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityTypeId"); + + b.ToTable("AbpAuthOrganizationUnitEntityRules", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowProperties") + .HasMaxLength(512) + .HasColumnType("varchar(512)") + .HasColumnName("AllowProperties"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("varchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("char(36)") + .HasColumnName("CreatorId"); + + b.Property("EntityTypeFullName") + .HasColumnType("longtext"); + + b.Property("EntityTypeId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ExtraProperties"); + + b.Property("FilterGroup") + .HasColumnType("longtext") + .HasColumnName("FilterGroup"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime(6)") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("char(36)") + .HasColumnName("LastModifierId"); + + b.Property("Operation") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)") + .HasColumnName("RoleName"); + + b.Property("TenantId") + .HasColumnType("char(36)") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityTypeId"); + + b.ToTable("AbpAuthRoleEntityRules", (string)null); + }); + modelBuilder.Entity("LINGYUN.Abp.Demo.Authors.Author", b => { b.Property("Id") @@ -5091,6 +5342,39 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AbpSettingDefinitions", (string)null); }); + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b => + { + b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "TypeInfo") + .WithMany("Properties") + .HasForeignKey("TypeInfoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TypeInfo"); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b => + { + b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo") + .WithMany() + .HasForeignKey("EntityTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EntityTypeInfo"); + }); + + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b => + { + b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo") + .WithMany() + .HasForeignKey("EntityTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EntityTypeInfo"); + }); + modelBuilder.Entity("LINGYUN.Abp.Demo.Books.Book", b => { b.HasOne("LINGYUN.Abp.Demo.Authors.Author", null) @@ -5435,6 +5719,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasForeignKey("AuthorizationId"); }); + modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b => + { + b.Navigation("Properties"); + }); + modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b => { b.Navigation("ConnectionStrings"); From 49381fb91bcdadf5eeacf58fa4edb2b68d32d0e3 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 18 Dec 2024 23:21:19 +0800 Subject: [PATCH 08/29] =?UTF-8?q?=F0=9F=9A=A7=20refactor(appsettings):=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4PostgreSql=E9=85=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E8=87=B3MySQL=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=85=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LY.AIO.Applications.Single.csproj | 2 +- ...rviceApplicationsSingleModule.Configure.cs | 6 +- .../MicroServiceApplicationsSingleModule.cs | 6 +- .../appsettings.Development.json | 16 +- .../appsettings.PostgreSql.json | 246 ------------------ 5 files changed, 15 insertions(+), 261 deletions(-) delete mode 100644 aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json diff --git a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj index d135a63ea..066e419db 100644 --- a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj +++ b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj @@ -37,7 +37,7 @@ - + diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs index f2f66239a..5ec0178f6 100644 --- a/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs +++ b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs @@ -569,10 +569,10 @@ private void ConfigureDbContext() { Configure(options => { - AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 - options.UseNpgsql(); + // AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + // options.UseNpgsql(); - // options.UseMySQL(); + options.UseMySQL(); }); } diff --git a/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs index a0c2ce2d6..b83019ebb 100644 --- a/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs +++ b/aspnet-core/services/LY.AIO.Applications.Single/MicroServiceApplicationsSingleModule.cs @@ -124,7 +124,7 @@ using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.Threading; // using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql; -// using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.EntityFrameworkCore.MySQL; namespace LY.AIO.Applications.Single; @@ -233,8 +233,8 @@ namespace LY.AIO.Applications.Single; typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理 - typeof(AbpEntityFrameworkCorePostgreSqlModule), - // typeof(AbpEntityFrameworkCoreMySQLModule), + // typeof(AbpEntityFrameworkCorePostgreSqlModule), + typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpAliyunSmsModule), typeof(AbpAliyunSettingManagementModule), diff --git a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json index a9d10fdff..4f753c08e 100644 --- a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json +++ b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.Development.json @@ -36,8 +36,8 @@ } }, "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 + "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, @@ -99,12 +99,12 @@ "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.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" } diff --git a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json b/aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json deleted file mode 100644 index cf15e11f7..000000000 --- a/aspnet-core/services/LY.AIO.Applications.Single/appsettings.PostgreSql.json +++ /dev/null @@ -1,246 +0,0 @@ -{ - "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": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer" - }, - "DistributedLock": { - "IsEnabled": true, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=14" - } - }, - "Elsa": { - "Features": { - "DefaultPersistence": { - "Enabled": false, - "ConnectionStringIdentifier": "Default", - "EntityFrameworkCore": { - "PostgreSql": { - "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": false, - "ConnectionStringIdentifier": "Default", - "EntityFrameworkCore": { - "PostgreSql": { - "Enabled": true - } - } - }, - "WorkflowSettings": { - "Enabled": false, - "ConnectionStringIdentifier": "Default", - "EntityFrameworkCore": { - "PostgreSql": { - "Enabled": true - } - } - } - }, - "Server": { - "BaseUrl": "http://127.0.0.1:30000" - } - }, - "Quartz": { - "UsePersistentStore": false, - "Properties": { - "quartz.jobStore.dataSource": "tkm", - "quartz.jobStore.useProperties": "true", - "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz", - "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", - "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer", - "quartz.dataSource.tkm.provider": "Npgsql", - "quartz.dataSource.tkm.connectionStringName": "Default", - "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" - } - } - ] - } -} From 06bc7f0b6c7e1cb348ae55ab2182c56253c93155 Mon Sep 17 00:00:00 2001 From: feijie Date: Sat, 28 Dec 2024 21:03:58 +0800 Subject: [PATCH 09/29] =?UTF-8?q?=F0=9F=94=A7=20chore(Directory.Packages.p?= =?UTF-8?q?rops):=20=E6=9B=B4=E6=96=B0Volo=E5=92=8CLINGYUN=E7=9A=84?= =?UTF-8?q?=E5=8C=85=E7=89=88=E6=9C=AC=E8=87=B38.3.0=20=F0=9F=A7=B9=20clea?= =?UTF-8?q?n(LY.AIO.Applications.Single.csproj):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E7=9A=84=E9=A1=B9=E7=9B=AE=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LY.AIO.Applications.Single.csproj | 8 - .../content/Directory.Packages.props | 173 +++++++++++++++++- 2 files changed, 170 insertions(+), 11 deletions(-) diff --git a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj index 066e419db..3b58f53e8 100644 --- a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj +++ b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj @@ -261,12 +261,4 @@ - - - - - - - - diff --git a/aspnet-core/templates/content/Directory.Packages.props b/aspnet-core/templates/content/Directory.Packages.props index f3dc78297..846a2c87c 100644 --- a/aspnet-core/templates/content/Directory.Packages.props +++ b/aspnet-core/templates/content/Directory.Packages.props @@ -2,8 +2,8 @@ 8.2.0 2.14.1 - 8.2.1 - 8.2.1 + 8.3.0 + 8.3.0 8.0.0 8.0.0 8.0.0 @@ -299,6 +299,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -319,5 +484,7 @@ + + - \ No newline at end of file + From 51e39dcbf2b55c30feb757306946081b3fcd3b7a Mon Sep 17 00:00:00 2001 From: feijie Date: Sat, 28 Dec 2024 21:34:05 +0800 Subject: [PATCH 10/29] =?UTF-8?q?=E2=9C=A8=20feat(template):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20AIO.Host=20=E9=A1=B9=E7=9B=AE=E5=88=B0=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=96=B9=E6=A1=88=E4=B8=AD=EF=BC=8C=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=A1=B9=E7=9B=AE=E6=96=87=E4=BB=B6=E4=BB=A5=E5=8C=85?= =?UTF-8?q?=E5=90=AB=E5=BF=85=E8=A6=81=E7=9A=84=E4=BE=9D=E8=B5=96=E9=A1=B9?= =?UTF-8?q?=E5=92=8C=E9=85=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LY.AIO.Applications.Single.csproj | 8 + .../content/Directory.Packages.props | 4 +- .../PackageName.CompanyName.ProjectName.sln | 7 + .../.config/dotnet-tools.json | 12 + .../.gitignore | 2 + .../AbpCookieAuthenticationHandler.cs | 89 ++ .../BackgroundJobs/NotificationPublishJob.cs | 38 + .../NotificationPublishJobArgs.cs | 22 + .../Controllers/HomeController.cs | 11 + .../Controllers/SettingMergeController.cs | 70 ++ .../Controllers/UserSettingMergeController.cs | 45 + .../Dockerfile | 19 + .../Distributed/ChatMessageEventHandler.cs | 59 ++ .../Distributed/NotificationEventHandler.cs | 470 +++++++++ .../Distributed/TenantSynchronizer.cs | 53 + .../Distributed/UserCreateEventHandler.cs | 30 + .../Distributed/WebhooksEventHandler.cs | 112 +++ .../Local/UserCreateJoinIMEventHandler.cs | 58 ++ .../UserCreateSendWelcomeEventHandler.cs | 69 ++ .../CustomIdentityResources.cs | 19 + ...rviceApplicationsSingleModule.Configure.cs | 935 ++++++++++++++++++ .../MicroServiceApplicationsSingleModule.cs | 394 ++++++++ ...eSiteCookiesServiceCollectionExtensions.cs | 67 ++ .../MultiTenancy/ITenantConfigurationCache.cs | 10 + .../MultiTenancy/TenantConfigurationCache.cs | 59 ++ .../TenantConfigurationCacheItem.cs | 19 + ...me.CompanyName.ProjectName.AIO.Host.csproj | 276 ++++++ .../PersonalInfo/Default.cshtml | 103 ++ .../PersonalInfo/Default.js | 28 + .../Pages/Account/EmailConfirm.cshtml | 17 + .../Pages/Account/EmailConfirm.cshtml.cs | 72 ++ .../Account/EmailConfirmConfirmation.cshtml | 13 + .../EmailConfirmConfirmation.cshtml.cs | 22 + .../Pages/Account/SendCode.cshtml | 26 + .../Pages/Account/SendCode.cshtml.cs | 125 +++ .../Pages/Account/SendEmailConfirm.cshtml | 16 + .../Pages/Account/SendEmailConfirm.cshtml.cs | 73 ++ .../Account/TwoFactorSupportedLoginModel.cs | 63 ++ .../Pages/Account/UseRecoveryCode.cshtml | 4 + .../Pages/Account/UseRecoveryCode.cshtml.cs | 11 + .../Account/VerifyAuthenticatorCode.cshtml | 26 + .../Account/VerifyAuthenticatorCode.cshtml.cs | 59 ++ .../Pages/Account/VerifyCode.cshtml | 29 + .../Pages/Account/VerifyCode.cshtml.cs | 90 ++ .../Pages/Index.cshtml | 36 + .../Pages/Index.cshtml.cs | 11 + .../Pages/_ViewImports.cshtml | 4 + .../Program.cs | 82 ++ .../Properties/launchSettings.json | 30 + .../TenantHeaderParamter.cs | 35 + .../Messages/TextMessageReplyContributor.cs | 21 + .../Messages/UserSubscribeEventContributor.cs | 21 + .../Messages/TextMessageReplyContributor.cs | 24 + .../appsettings.Development.json | 249 +++++ .../appsettings.json | 89 ++ .../gulpfile.js | 10 + 56 files changed, 4344 insertions(+), 2 deletions(-) create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json create mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js diff --git a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj index 3b58f53e8..0fbfdd223 100644 --- a/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj +++ b/aspnet-core/services/LY.AIO.Applications.Single/LY.AIO.Applications.Single.csproj @@ -261,4 +261,12 @@ + + + + + + + + diff --git a/aspnet-core/templates/content/Directory.Packages.props b/aspnet-core/templates/content/Directory.Packages.props index 846a2c87c..433f06afb 100644 --- a/aspnet-core/templates/content/Directory.Packages.props +++ b/aspnet-core/templates/content/Directory.Packages.props @@ -484,7 +484,7 @@ - - + + diff --git a/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln b/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln index f66e0df1f..8d3a5d224 100644 --- a/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln +++ b/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln @@ -50,6 +50,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.Pro EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.SettingManagement", "src\PackageName.CompanyName.ProjectName.SettingManagement\PackageName.CompanyName.ProjectName.SettingManagement.csproj", "{CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageName.CompanyName.ProjectName.AIO.Host", "host\PackageName.CompanyName.ProjectName.AIO.Host\PackageName.CompanyName.ProjectName.AIO.Host.csproj", "{26F1E2F7-3B0E-4333-9E66-EFE0D113386B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -116,6 +118,10 @@ Global {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Debug|Any CPU.Build.0 = Debug|Any CPU {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Release|Any CPU.ActiveCfg = Release|Any CPU {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Release|Any CPU.Build.0 = Release|Any CPU + {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -136,6 +142,7 @@ Global {FDB3A3E9-C072-438D-8B8D-2AA957C1167F} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} {8CE7C515-CD78-42D4-A9D7-39D217A3D046} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} + {26F1E2F7-3B0E-4333-9E66-EFE0D113386B} = {4786387C-C1C5-46F8-806F-EBC54DB0A4FA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {62C0F185-E2C2-46A2-B4B2-5E703E25849E} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json new file mode 100644 index 000000000..6b93cca86 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "7.0.3", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore new file mode 100644 index 000000000..7b6f60857 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore @@ -0,0 +1,2 @@ +wwwroot +package*.json \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs new file mode 100644 index 000000000..34517090f --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs @@ -0,0 +1,89 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.Extensions.Options; +using System.Text.Encodings.Web; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Authentication; + +public class AbpCookieAuthenticationHandler : CookieAuthenticationHandler +{ + public AbpCookieAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder) : base(options, logger, encoder) + { + } + + public AbpCookieAuthenticationHandler( + IOptionsMonitor 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; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs new file mode 100644 index 000000000..c9db9977a --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs @@ -0,0 +1,38 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Options; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs; + +public class NotificationPublishJob : AsyncBackgroundJob, ITransientDependency +{ + protected AbpNotificationsPublishOptions Options { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } + protected INotificationDataSerializer NotificationDataSerializer { get; } + public NotificationPublishJob( + IOptions 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(); + var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); + notification.Data = NotificationDataSerializer.Serialize(notification.Data); + + await publishProvider.PublishAsync(notification, args.UserIdentifiers); + } + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs new file mode 100644 index 000000000..e5f077d65 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.Notifications; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs; + +public class NotificationPublishJobArgs +{ + public Guid? TenantId { get; set; } + public long NotificationId { get; set; } + public string ProviderType { get; set; } + public List UserIdentifiers { get; set; } + public NotificationPublishJobArgs() + { + UserIdentifiers = new List(); + } + public NotificationPublishJobArgs(long id, string providerType, List userIdentifiers, Guid? tenantId = null) + { + NotificationId = id; + ProviderType = providerType; + UserIdentifiers = userIdentifiers; + TenantId = tenantId; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs new file mode 100644 index 000000000..e693a0917 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; + +public class HomeController : Controller +{ + public IActionResult Index() + { + return Redirect("/swagger"); + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs new file mode 100644 index 000000000..11e91bd88 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs @@ -0,0 +1,70 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; + +[ExposeServices( + typeof(SettingController), + typeof(SettingMergeController))] +public class SettingMergeController : SettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public SettingMergeController( + ISettingAppService settingAppService, + ISettingTestAppService settingTestAppService, + IOptions mergeOptions) + : base(settingAppService, settingTestAppService) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-tenant")] + public async override Task GetAllForCurrentTenantAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + 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 GetAllForGlobalAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForGlobalAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs new file mode 100644 index 000000000..5091a8a5e --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; + +[ExposeServices( + typeof(UserSettingController), + typeof(UserSettingMergeController))] +public class UserSettingMergeController : UserSettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public UserSettingMergeController( + IUserSettingAppService service, + IOptions mergeOptions) + : base(service) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-user")] + public async override Task GetAllForCurrentUserAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(UserSettingMergeController), + }; + foreach (var serviceType in _mergeOptions.UserSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentUserAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile new file mode 100644 index 000000000..aee09fd66 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile @@ -0,0 +1,19 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +LABEL maintainer="colin.in@foxmail.com" +WORKDIR /app + +COPY . /app + +#东8区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone + +EXPOSE 80/tcp +VOLUME [ "./app/blobs" ] +VOLUME [ "./app/Logs" ] +VOLUME [ "./app/Modules" ] + +RUN apt update +RUN apt install wget -y + +ENTRYPOINT ["dotnet", "LY.MicroService.Applications.Single.dll"] diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs new file mode 100644 index 000000000..a08702a0a --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.IM; +using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.RealTime; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + public class ChatMessageEventHandler : IDistributedEventHandler>, ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpIMOptions Options { get; } + + protected IMessageStore MessageStore { get; } + protected IMessageBlocker MessageBlocker { get; } + protected IMessageSenderProviderManager MessageSenderProviderManager { get; } + + public ChatMessageEventHandler( + IOptions options, + IMessageStore messageStore, + IMessageBlocker messageBlocker, + IMessageSenderProviderManager messageSenderProviderManager) + { + Options = options.Value; + MessageStore = messageStore; + MessageBlocker = messageBlocker; + MessageSenderProviderManager = messageSenderProviderManager; + + Logger = NullLogger.Instance; + } + + public async virtual Task HandleEventAsync(RealTimeEto 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); + } + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs new file mode 100644 index 000000000..cb871c6ef --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs @@ -0,0 +1,470 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs; +using PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; +using System.Globalization; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Json; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.TextTemplating; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + /// + /// 订阅通知发布事件,统一发布消息 + /// + /// + /// 作用在于SignalR客户端只会与一台服务器建立连接, + /// 只有启用了SignlR服务端的才能真正将消息发布到客户端 + /// + public class NotificationEventHandler : + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpNotificationsPublishOptions Options { get; } + /// + /// Reference to . + /// + protected ICurrentTenant CurrentTenant { get; } + /// + /// Reference to . + /// + protected ITenantConfigurationCache TenantConfigurationCache { get; } + /// + /// Reference to . + /// + protected IJsonSerializer JsonSerializer { get; } + /// + /// Reference to . + /// + protected IBackgroundJobManager BackgroundJobManager { get; } + /// + /// Reference to . + /// + protected ITemplateRenderer TemplateRenderer { get; } + /// + /// Reference to . + /// + protected INotificationStore NotificationStore { get; } + /// + /// Reference to . + /// + protected IStringLocalizerFactory StringLocalizerFactory { get; } + /// + /// Reference to . + /// + protected INotificationDataSerializer NotificationDataSerializer { get; } + /// + /// Reference to . + /// + protected INotificationDefinitionManager NotificationDefinitionManager { get; } + /// + /// Reference to . + /// + protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } + /// + /// Reference to . + /// + protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } + + /// + /// Initializes a new instance of the class. + /// + public NotificationEventHandler( + ICurrentTenant currentTenant, + ITenantConfigurationCache tenantConfigurationCache, + IJsonSerializer jsonSerializer, + ITemplateRenderer templateRenderer, + IBackgroundJobManager backgroundJobManager, + IStringLocalizerFactory stringLocalizerFactory, + IOptions 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.Instance; + } + + [UnitOfWork] + public async virtual Task HandleEventAsync(NotificationEto 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 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 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 + { + // 模板不支持 $ 字符, 改为普通关键字 + { 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 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); + } + } + } + } + /// + /// 获取用户订阅列表 + /// + /// 通知名称 + /// 接收用户列表 + /// 租户标识 + /// 用户订阅列表 + protected async Task> GerSubscriptionUsersAsync( + string notificationName, + IEnumerable 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(); + } + /// + /// 持久化通知并返回订阅用户列表 + /// + /// 通知实体 + /// 订阅用户列表 + /// 通知发送提供者 + /// 返回订阅者列表 + protected async Task PersistentNotificationAsync( + NotificationInfo notificationInfo, + IEnumerable subscriptionUsers, + IEnumerable 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); + } + } + } + /// + /// 发布订阅者通知 + /// + /// 通知发布者 + /// 通知信息 + /// 订阅用户列表 + /// + protected async Task PublishToSubscriberAsync( + INotificationPublishProvider provider, + NotificationInfo notificationInfo, + IEnumerable 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); + } + } + /// + /// 处理失败的消息进入后台队列 + /// + /// + /// 注: 如果入队失败,消息将被丢弃. + /// + /// + /// + /// + /// + protected async Task ProcessingFailedToQueueAsync( + INotificationPublishProvider provider, + NotificationInfo notificationInfo, + IEnumerable 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); + } + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs new file mode 100644 index 000000000..3e07d5be9 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs @@ -0,0 +1,53 @@ +using LINGYUN.Abp.Saas.Tenants; +using PackageName.CompanyName.ProjectName.AIO.Host.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 PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + public class TenantSynchronizer : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler, + 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 eventData) + { + await TenantConfigurationCache.RefreshAsync(); + + await DataSeeder.SeedAsync(eventData.Entity.Id); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + + public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs new file mode 100644 index 000000000..ee5ab700b --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs @@ -0,0 +1,30 @@ +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.EventBus.Local; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + public class UserCreateEventHandler : IDistributedEventHandler>, ITransientDependency + { + private readonly ILocalEventBus _localEventBus; + public UserCreateEventHandler( + ILocalEventBus localEventBus) + { + _localEventBus = localEventBus; + } + /// + /// 接收添加用户事件,发布本地事件 + /// + /// + /// + public async Task HandleEventAsync(EntityCreatedEto eventData) + { + var localUserCreateEventData = new EntityCreatedEventData(eventData.Entity); + + await _localEventBus.PublishAsync(localUserCreateEventData); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs new file mode 100644 index 000000000..eeb0fcdb7 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs @@ -0,0 +1,112 @@ +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.Webhooks.EventBus; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed; + +public class WebhooksEventHandler : + IDistributedEventHandler, + 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 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 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; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs new file mode 100644 index 000000000..2b78e5841 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs @@ -0,0 +1,58 @@ +using LINGYUN.Abp.MessageService.Chat; +using LINGYUN.Abp.MessageService.Notifications; +using LINGYUN.Abp.Notifications; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.Uow; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Local +{ + public class UserCreateJoinIMEventHandler : ILocalEventHandler>, ITransientDependency + { + private readonly IChatDataSeeder _chatDataSeeder; + private readonly INotificationSubscriptionManager _notificationSubscriptionManager; + public UserCreateJoinIMEventHandler( + IChatDataSeeder chatDataSeeder, + INotificationSubscriptionManager notificationSubscriptionManager) + { + _chatDataSeeder = chatDataSeeder; + _notificationSubscriptionManager = notificationSubscriptionManager; + } + /// + /// 接收添加用户事件,初始化IM用户种子 + /// + /// + /// + [UnitOfWork] + public async virtual Task HandleEventAsync(EntityCreatedEventData 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); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs new file mode 100644 index 000000000..8176df498 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs @@ -0,0 +1,69 @@ +using LINGYUN.Abp.Notifications; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Local +{ + public class UserCreateSendWelcomeEventHandler : ILocalEventHandler>, ITransientDependency + { + private readonly INotificationSender _notificationSender; + private readonly INotificationSubscriptionManager _notificationSubscriptionManager; + public UserCreateSendWelcomeEventHandler( + INotificationSender notificationSender, + INotificationSubscriptionManager notificationSubscriptionManager + ) + { + _notificationSender = notificationSender; + _notificationSubscriptionManager = notificationSubscriptionManager; + } + + public async Task HandleEventAsync(EntityCreatedEventData 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 + { + { "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); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs new file mode 100644 index 000000000..99fce8c22 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs @@ -0,0 +1,19 @@ +using LINGYUN.Abp.Identity; +using IdentityServer4.Models; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 }; + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs new file mode 100644 index 000000000..cbc4e883a --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs @@ -0,0 +1,935 @@ +using Elsa; +using Elsa.Options; +using LINGYUN.Abp.Aliyun.Localization; +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.DataProtectionManagement; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Exporter.MiniExcel; +using LINGYUN.Abp.Idempotent; +using LINGYUN.Abp.Identity.Session; +using LINGYUN.Abp.IdentityServer.IdentityResources; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Notifications; +using LINGYUN.Abp.OpenIddict.AspNetCore.Session; +using LINGYUN.Abp.OpenIddict.LinkUser; +using LINGYUN.Abp.OpenIddict.Permissions; +using LINGYUN.Abp.OpenIddict.Portal; +using LINGYUN.Abp.OpenIddict.Sms; +using LINGYUN.Abp.OpenIddict.WeChat; +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.Tencent.Localization; +using LINGYUN.Abp.TextTemplating; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Localization; +using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.Wrapper; +using LINGYUN.Platform.Localization; +using PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection; +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 PackageName.CompanyName.ProjectName.AIO.Host.Authentication; +using PackageName.CompanyName.ProjectName.AIO.Host.IdentityResources; +using PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; +using Quartz; +using StackExchange.Redis; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +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 PackageName.CompanyName.ProjectName.AIO.Host; + +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(options => + { + // 以开放端口区别,应在0-31之间 + options.SnowflakeIdOptions.WorkerId = 1; + options.SnowflakeIdOptions.WorkerIdBits = 5; + options.SnowflakeIdOptions.DatacenterId = 1; + }); + + if (configuration.GetValue("App:ShowPii")) + { + IdentityModelEventSource.ShowPII = true; + } + } + + private void PreConfigureAuthServer(IConfiguration configuration) + { + PreConfigure(builder => + { + builder.AddValidation(options => + { + //options.AddAudiences("lingyun-abp-application"); + + options.UseLocalServer(); + + options.UseAspNetCore(); + + options.UseDataProtection(); + }); + }); + } + + private void PreConfigureIdentity() + { + PreConfigure(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("AuthServer:UseOpenIddict")) + { + PreConfigure(options => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(builder => + { + builder.AddSigningCertificate(certificate); + builder.AddEncryptionCertificate(certificate); + + builder.UseDataProtection(); + + // 禁用https + builder.UseAspNetCore() + .DisableTransportSecurityRequirement(); + }); + } + else + { + PreConfigure(options => + { + options.AddDeveloperSigningCredential = false; + }); + + PreConfigure(builder => + { + builder.AddSigningCredential(certificate); + }); + } + } + } + else + { + if (configuration.GetValue("AuthServer:UseOpenIddict")) + { + PreConfigure(options => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(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(options => + { + // 如果使用持久化存储, 则配置quartz持久层 + if (configuration.GetSection("Quartz:UsePersistentStore").Get()) + { + var settings = configuration.GetSection("Quartz:Properties").Get>(); + 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(elsa => + { + elsa + .AddActivitiesFrom() + .AddWorkflowsFrom() + .AddFeatures(startups, configuration) + .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)); + + elsa.DistributedLockingOptionsBuilder + .UseProviderFactory(sp => name => + { + var provider = sp.GetRequiredService(); + + return provider.CreateLock(name); + }); + }); + + services.AddNotificationHandlersFrom(); + + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(Elsa.Webhooks.Api.Endpoints.List).Assembly); + }); + } + + private void ConfigureAuthServer(IConfiguration configuration) + { + Configure(builder => + { + builder.DisableTransportSecurityRequirement(); + }); + + Configure(options => + { + options.DisableTransportSecurityRequirement = true; + }); + + Configure(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(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(options => + //{ + // options.EndpointConfigureActions.Add( + // (context) => + // { + // context.Endpoints.MapFallbackToPage("/_Host"); + // }); + //}); + var preActions = services.GetPreConfigureActions(); + + 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(options => + { + options.Limits.MaxRequestBodySize = null; + options.Limits.MaxRequestBufferSize = null; + }); + } + + private void ConfigureBlobStoring(IConfiguration configuration) + { + Configure(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(options => + { + options.NodeName = ApplicationName; + options.JobCleanEnabled = true; + options.JobFetchEnabled = true; + options.JobCheckEnabled = true; + }); + } + + private void ConfigureTextTemplating(IConfiguration configuration) + { + if (configuration.GetValue("TextTemplating:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicTemplateDefinitionStoreEnabled = true; + }); + } + } + + private void ConfigureFeatureManagement(IConfiguration configuration) + { + if (configuration.GetValue("FeatureManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicFeatureStoreEnabled = true; + }); + } + Configure(options => + { + options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = AbpSaasPermissions.Editions.ManageFeatures; + options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = AbpSaasPermissions.Tenants.ManageFeatures; + }); + } + + private void ConfigureSettingManagement(IConfiguration configuration) + { + if (configuration.GetValue("SettingManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicSettingStoreEnabled = true; + }); + } + } + + private void ConfigureWebhooksManagement(IConfiguration configuration) + { + if (configuration.GetValue("WebhooksManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicWebhookStoreEnabled = true; + }); + } + } + /// + /// 配置数据导出 + /// + private void ConfigureExporter() + { + Configure(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 }, + // }; + // }); + }); + } + /// + /// 配置数据权限 + /// + private void ConfigureEntityDataProtected() + { + // Configure(options => + // { + // options.AddEntities(typeof(DemoResource), + // new[] + // { + // typeof(Book), + // }); + // }); + } + + private void ConfigurePermissionManagement(IConfiguration configuration) + { + if (configuration.GetValue("PermissionManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicPermissionStoreEnabled = true; + }); + } + Configure(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("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("NotificationsManagement:IsDynamicStoreEnabled")) + { + Configure(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(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); + } + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LY.MicroService.Applications.Single"); + }); + } + + private void ConfigureIdempotent() + { + Configure(options => + { + options.IsEnabled = true; + options.DefaultTimeout = 0; + }); + } + + private void ConfigureDbContext() + { + Configure(options => + { + // AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + // options.UseNpgsql(); + + options.UseMySQL(); + }); + } + + private void ConfigureDataSeeder() + { + Configure(options => + { + options.Resources.Add(new CustomIdentityResources.AvatarUrl()); + }); + } + + private void ConfigureExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + // 未指定异常接收者的默认接收邮件 + // 指定自己的邮件地址 + }); + + Configure(options => + { + options.SendStackTraceToClients = false; + options.SendExceptionsDetailsToClients = false; + }); + } + + private void ConfigureJsonSerializer(IConfiguration configuration) + { + // 统一时间日期格式 + Configure(options => + { + var jsonConfiguration = configuration.GetSection("Json"); + if (jsonConfiguration.Exists()) + { + jsonConfiguration.Bind(options); + } + }); + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + configuration.GetSection("DistributedCache").Bind(options); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(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(); + }); + } + + private void ConfigureIdentity(IConfiguration configuration) + { + // 增加配置文件定义,在新建租户时需要 + Configure(options => + { + var identityConfiguration = configuration.GetSection("Identity"); + if (identityConfiguration.Exists()) + { + identityConfiguration.Bind(options); + } + }); + Configure(options => + { + options.IsDynamicClaimsEnabled = true; + }); + Configure(options => + { + options.IsCleanupEnabled = true; + }); + } + + private void ConfigureMvcUiTheme() + { + Configure(options => + { + //options.StyleBundles.Configure( + // LeptonXLiteThemeBundles.Styles.Global, + // bundle => + // { + // bundle.AddFiles("/global-styles.css"); + // } + //); + }); + } + + private void ConfigureLocalization() + { + Configure(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() + .AddBaseTypes( + typeof(IdentityResource), + typeof(AliyunResource), + typeof(TencentCloudResource), + typeof(WeChatResource), + typeof(PlatformResource), + typeof(AbpOpenIddictResource), + typeof(AbpIdentityServerResource)); + + options.UseAllPersistence(); + }); + + Configure(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(options => + { + options.IsEnabled = true; + // options.IsWrapUnauthorizedEnabled = true; + options.IgnoreNamespaces.Add("Elsa"); + }); + } + + private void PreConfigureWrapper() + { + //PreConfigure(options => + //{ + // options.ProxyRequestActions.Add( + // (appid, httprequestmessage) => + // { + // httprequestmessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + // }); + //}); + + PreConfigure(options => + { + options.ProxyClientActions.Add( + (_, _, client) => + { + client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + }); + }); + } + + private void ConfigureAuditing() + { + Configure(options => + { + // options.IsEnabledForGetRequests = true; + options.ApplicationName = ApplicationName; + }); + } + + private void ConfigureUrls(IConfiguration configuration) + { + Configure(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(options => + { + options.AutoValidate = false; + }); + + services.Replace(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(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>(); + }); + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs new file mode 100644 index 000000000..ceb61611a --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs @@ -0,0 +1,394 @@ +using LINGYUN.Abp.Account; +using LINGYUN.Abp.Account.Templates; +using LINGYUN.Abp.Aliyun.SettingManagement; +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper; +using LINGYUN.Abp.AspNetCore.Mvc.Localization; +using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.Auditing; +using LINGYUN.Abp.AuditLogging.EntityFrameworkCore; +using LINGYUN.Abp.Authentication.QQ; +using LINGYUN.Abp.Authentication.WeChat; +using LINGYUN.Abp.Authorization.OrganizationUnits; +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.BackgroundTasks.Activities; +using LINGYUN.Abp.BackgroundTasks.DistributedLocking; +using LINGYUN.Abp.BackgroundTasks.EventBus; +using LINGYUN.Abp.BackgroundTasks.ExceptionHandling; +using LINGYUN.Abp.BackgroundTasks.Jobs; +using LINGYUN.Abp.BackgroundTasks.Notifications; +using LINGYUN.Abp.BackgroundTasks.Quartz; +using LINGYUN.Abp.CachingManagement; +using LINGYUN.Abp.CachingManagement.StackExchangeRedis; +using LINGYUN.Abp.Dapr.Client; +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.DataProtectionManagement; +using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore; +// using LINGYUN.Abp.Demo; +// using LINGYUN.Abp.Demo.EntityFrameworkCore; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Exporter.MiniExcel; +using LINGYUN.Abp.FeatureManagement; +using LINGYUN.Abp.FeatureManagement.HttpApi; +using LINGYUN.Abp.Features.LimitValidation; +using LINGYUN.Abp.Features.LimitValidation.Redis.Client; +using LINGYUN.Abp.Http.Client.Wrapper; +using LINGYUN.Abp.Identity; +using LINGYUN.Abp.Identity.AspNetCore.Session; +using LINGYUN.Abp.Identity.EntityFrameworkCore; +using LINGYUN.Abp.Identity.Notifications; +using LINGYUN.Abp.Identity.OrganizaztionUnits; +using LINGYUN.Abp.Identity.Session.AspNetCore; +using LINGYUN.Abp.Identity.WeChat; +using LINGYUN.Abp.IdGenerator; +using LINGYUN.Abp.IM.SignalR; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Localization.Persistence; +using LINGYUN.Abp.LocalizationManagement; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MessageService; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using LINGYUN.Abp.MultiTenancy.Editions; +using LINGYUN.Abp.Notifications; +using LINGYUN.Abp.Notifications.Common; +using LINGYUN.Abp.Notifications.Emailing; +using LINGYUN.Abp.Notifications.EntityFrameworkCore; +using LINGYUN.Abp.Notifications.SignalR; +using LINGYUN.Abp.Notifications.WeChat.MiniProgram; +using LINGYUN.Abp.OpenApi.Authorization; +using LINGYUN.Abp.OpenIddict; +using LINGYUN.Abp.OpenIddict.AspNetCore; +using LINGYUN.Abp.OpenIddict.AspNetCore.Session; +using LINGYUN.Abp.OpenIddict.Portal; +using LINGYUN.Abp.OpenIddict.Sms; +using LINGYUN.Abp.OpenIddict.WeChat; +using LINGYUN.Abp.OpenIddict.WeChat.Work; +using LINGYUN.Abp.OssManagement; +using LINGYUN.Abp.OssManagement.FileSystem; +// using LINGYUN.Abp.OssManagement.Imaging; +using LINGYUN.Abp.OssManagement.SettingManagement; +using LINGYUN.Abp.PermissionManagement; +using LINGYUN.Abp.PermissionManagement.HttpApi; +using LINGYUN.Abp.PermissionManagement.OrganizationUnits; +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.SettingManagement; +using LINGYUN.Abp.Sms.Aliyun; +using LINGYUN.Abp.TaskManagement; +using LINGYUN.Abp.TaskManagement.EntityFrameworkCore; +using LINGYUN.Abp.Tencent.QQ; +using LINGYUN.Abp.Tencent.SettingManagement; +using LINGYUN.Abp.TextTemplating; +using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; +using LINGYUN.Abp.UI.Navigation; +using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.Webhooks.EventBus; +using LINGYUN.Abp.Webhooks.Identity; +using LINGYUN.Abp.Webhooks.Saas; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; +using LINGYUN.Abp.WeChat.MiniProgram; +using LINGYUN.Abp.WeChat.Official; +using LINGYUN.Abp.WeChat.Official.Handlers; +using LINGYUN.Abp.WeChat.SettingManagement; +using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.WeChat.Work.Handlers; +using LINGYUN.Platform; +using LINGYUN.Platform.EntityFrameworkCore; +using LINGYUN.Platform.HttpApi; +using LINGYUN.Platform.Settings.VueVbenAdmin; +using LINGYUN.Platform.Theme.VueVbenAdmin; +using Volo.Abp; +using Volo.Abp.Account.Web; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore.PostgreSql; +using Volo.Abp.EventBus; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Imaging; +using Volo.Abp.Modularity; +using Volo.Abp.OpenIddict.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.Identity; +using Volo.Abp.PermissionManagement.OpenIddict; +using Volo.Abp.SettingManagement; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.Threading; +// using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql; +using Volo.Abp.EntityFrameworkCore.MySQL; + +namespace PackageName.CompanyName.ProjectName.AIO.Host; + +[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().SeedAsync(); ; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs new file mode 100644 index 000000000..42108b0eb --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs @@ -0,0 +1,67 @@ +namespace PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection +{ + public static class SameSiteCookiesServiceCollectionExtensions + { + public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services) + { + services.Configure(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; + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs new file mode 100644 index 000000000..daabe255d --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs @@ -0,0 +1,10 @@ +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; + +public interface ITenantConfigurationCache +{ + Task RefreshAsync(); + + Task> GetTenantsAsync(); +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs new file mode 100644 index 000000000..61f939f97 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.Saas.Tenants; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; + +public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency +{ + protected ITenantRepository TenantRepository { get; } + protected IDistributedCache TenantCache { get; } + + public TenantConfigurationCache( + ITenantRepository tenantRepository, + IDistributedCache tenantCache) + { + TenantRepository = tenantRepository; + TenantCache = tenantCache; + } + + public async virtual Task RefreshAsync() + { + var cacheKey = GetCacheKey(); + + await TenantCache.RemoveAsync(cacheKey); + } + + public async virtual Task> GetTenantsAsync() + { + return (await GetForCacheItemAsync()).Tenants; + } + + protected async virtual Task 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"; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs new file mode 100644 index 000000000..ac10549e5 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs @@ -0,0 +1,19 @@ +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; + +[IgnoreMultiTenancy] +public class TenantConfigurationCacheItem +{ + public List Tenants { get; set; } + + public TenantConfigurationCacheItem() + { + Tenants = new List(); + } + + public TenantConfigurationCacheItem(List tenants) + { + Tenants = tenants; + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj new file mode 100644 index 000000000..136d24605 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj @@ -0,0 +1,276 @@ + + + net8.0 + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml new file mode 100644 index 000000000..aed9202eb --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml @@ -0,0 +1,103 @@ +@using Volo.Abp.Account.Localization +@using Volo.Abp.Users +@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.Extensions.Localization +@using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using Volo.Abp.Data +@using Volo.Abp.Identity.Settings +@using Volo.Abp.Localization +@using Volo.Abp.Settings +@using Volo.Abp.ObjectExtending +@inject IHtmlLocalizer 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); +} + +

@L["PersonalSettings"]


+
+ + + + + + + + + + + + + + + + + + + + @if (CurrentUser.EmailVerified) + { + + } + else + { + @**@ + @L["Validation"].Value + } + + + + + + @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + { + 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); + } + + + } + else + { + + } + } + } + + + diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js new file mode 100644 index 000000000..55a88e52e --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js @@ -0,0 +1,28 @@ +(function ($) { + $(function () { + var l = abp.localization.getResource("AbpAccount"); + + $('#PersonalSettingsForm').submit(function (e) { + e.preventDefault(); + + if (!$('#PersonalSettingsForm').valid()) { + return false; + } + + var input = $('#PersonalSettingsForm').serializeFormToObject(); + + volo.abp.account.profile.update(input).then(function (result) { + abp.notify.success(l('PersonalSettingsSaved')); + updateConcurrencyStamp(); + }); + }); + }); + + abp.event.on('passwordChanged', updateConcurrencyStamp); + + function updateConcurrencyStamp(){ + volo.abp.account.profile.get().then(function(profile){ + $("#ConcurrencyStamp").val(profile.concurrencyStamp); + }); + } +})(jQuery); diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml new file mode 100644 index 000000000..d4d8cda0f --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml @@ -0,0 +1,17 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.EmailConfirmModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +
+
+

@L["EmailConfirm"]

+
+ + + @L["Cancel"] + + +
+
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs new file mode 100644 index 000000000..b2ed2b28e --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs @@ -0,0 +1,72 @@ +using LINGYUN.Abp.Account; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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 + }); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml new file mode 100644 index 000000000..8ffc6586b --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml @@ -0,0 +1,13 @@ +@page +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.EmailConfirmConfirmationModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@inject IHtmlLocalizer L +
+
+

@L["EmailConfirm"]

+

@L["YourEmailIsSuccessfullyConfirm"]

+ @L["GoToTheApplication"] +
+
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs new file mode 100644 index 000000000..01f1f0f01 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Account.Web.Pages.Account; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 OnGetAsync() + { + ReturnUrl = await GetRedirectUrlAsync(ReturnUrl, ReturnUrlHash); + + return Page(); + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml new file mode 100644 index 000000000..8d55fdd34 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml @@ -0,0 +1,26 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.SendCodeModel +@inject IHtmlLocalizer L + +
+
+

@L["TwoFactor"]

+
+ + + +
+ +
+
+ @L["SendVerifyCode"] +
+ + @L["Login"] + + +
+
+ diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs new file mode 100644 index 000000000..8155e20f1 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs @@ -0,0 +1,125 @@ +using LINGYUN.Abp.Account.Emailing; +using LINGYUN.Abp.Identity.Settings; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Volo.Abp; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Sms; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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 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 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; } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml new file mode 100644 index 000000000..8f0dd7030 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml @@ -0,0 +1,16 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.SendEmailConfirmModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +
+
+

@L["EmailConfirm"]

+
+ + @L["Cancel"] + + +
+
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs new file mode 100644 index 000000000..9d14d5710 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs @@ -0,0 +1,73 @@ +using LINGYUN.Abp.Account; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 OnGetAsync() + { + Email = CurrentUser.Email; + + return Task.FromResult(Page()); + } + + public async virtual Task 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 + }); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs new file mode 100644 index 000000000..166f827e9 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.Account.Web; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.OpenIddict; +using IdentityOptions = Microsoft.AspNetCore.Identity.IdentityOptions; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account +{ + /// + /// 重写登录模型,实现双因素登录 + /// + [Dependency(ReplaceServices = true)] + [ExposeServices(typeof(LoginModel), typeof(OpenIddictSupportedLoginModel))] + public class TwoFactorSupportedLoginModel : OpenIddictSupportedLoginModel + { + public TwoFactorSupportedLoginModel( + IAuthenticationSchemeProvider schemeProvider, + IOptions accountOptions, + IOptions identityOptions, + IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache, + AbpOpenIddictRequestHelper openIddictRequestHelper) + : base(schemeProvider, accountOptions, identityOptions, identityDynamicClaimsPrincipalContributorCache, openIddictRequestHelper) + { + + } + + protected async override Task> 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 TwoFactorLoginResultAsync() + { + // 重定向双因素认证页面 + return Task.FromResult(RedirectToPage("SendCode", new + { + returnUrl = ReturnUrl, + returnUrlHash = ReturnUrlHash, + rememberMe = LoginInput.RememberMe + })); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml new file mode 100644 index 000000000..1936197c0 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml @@ -0,0 +1,4 @@ +@page +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.UseRecoveryCodeModel +@{ +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs new file mode 100644 index 000000000..c8ccca339 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account +{ + public class UseRecoveryCodeModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml new file mode 100644 index 000000000..2b14e2168 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml @@ -0,0 +1,26 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.VerifyAuthenticatorCodeModel +@inject IHtmlLocalizer L +
+
+
+ + +
+ + + +
+
+ + +
+ @L["VerifyAuthenticatorCode"] + + @L["Login"] + +
+
+
\ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs new file mode 100644 index 000000000..899e3df30 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Web.Pages.Account; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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; } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml new file mode 100644 index 000000000..44d45b36e --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml @@ -0,0 +1,29 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.VerifyCodeModel +
+
+
+ + + + +
+ +
+ + + + + +
+ @L["VerifyAuthenticatorCode"] +
+ + @L["ReSendVerifyCode"] + +
+
+
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs new file mode 100644 index 000000000..169c48eda --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account +{ + public class VerifyCodeModel : AccountPageModel + { + [BindProperty] + public VerifyCodeInputModel Input { get; set; } + /// + /// ˫������֤�ṩ���� + /// + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string Provider { get; set; } + /// + /// �ض���Url + /// + [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 VerifyCodeModel() + { + LocalizationResourceType = typeof(AccountResource); + } + + public virtual IActionResult OnGet() + { + Input = new VerifyCodeInputModel(); + + return Page(); + } + + public virtual async Task 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 + { + /// + /// �Ƿ���������м�ס��¼״̬ + /// + public bool RememberBrowser { get; set; } + /// + /// ���͵���֤�� + /// + [Required] + public string VerifyCode { get; set; } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml new file mode 100644 index 000000000..c149bd95d --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml @@ -0,0 +1,36 @@ +@page +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Alert +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid +@using Volo.Abp.Users +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.IndexModel +@inject ICurrentUser CurrentUser +@if (CurrentUser.IsAuthenticated) +{ +
+ + + + Logout + + +

@CurrentUser.UserName

+
@CurrentUser.Email
+
+ Roles: @CurrentUser.Roles.JoinAsString(", ") +
+ Claims:
+ @Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString("
")) +
+
+
+
+} + +@if (!CurrentUser.IsAuthenticated) +{ +
+

+ Login +
+} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs new file mode 100644 index 000000000..7047bc406 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages +{ + public class IndexModel : AbpPageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml new file mode 100644 index 000000000..c1da1f5f1 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs new file mode 100644 index 000000000..3daf07fe4 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs @@ -0,0 +1,82 @@ +using LINGYUN.Abp.Identity.Session.AspNetCore; +using PackageName.CompanyName.ProjectName.AIO.Host; +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(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(); diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json new file mode 100644 index 000000000..337677308 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:19139", + "sslPort": 0 + } + }, + "profiles": { + "LY.MicroService.Applications.Single": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://0.0.0.0:30001", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Production" + } + }, + "LY.MicroService.Applications.Single.Development": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://0.0.0.0:30000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs new file mode 100644 index 000000000..a4218a9c4 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host; + +public class TenantHeaderParamter : IOperationFilter +{ + private readonly AbpMultiTenancyOptions _multiTenancyOptions; + private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions; + public TenantHeaderParamter( + IOptions multiTenancyOptions, + IOptions aspNetCoreMultiTenancyOptions) + { + _multiTenancyOptions = multiTenancyOptions.Value; + _aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value; + } + + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (_multiTenancyOptions.IsEnabled) + { + operation.Parameters = operation.Parameters ?? new List(); + operation.Parameters.Add(new OpenApiParameter + { + Name = _aspNetCoreMultiTenancyOptions.TenantKey, + In = ParameterLocation.Header, + Description = "Tenant Id in http header", + Required = false + }); + } + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs new file mode 100644 index 000000000..31aafda51 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Official.Messages.Models; +using LINGYUN.Abp.WeChat.Official.Services; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; +/// +/// 文本消息客服回复 +/// +public class TextMessageReplyContributor : IMessageHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + 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))); + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs new file mode 100644 index 000000000..806302c0d --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Official.Messages.Models; +using LINGYUN.Abp.WeChat.Official.Services; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; +/// +/// 用户关注回复消息 +/// +public class UserSubscribeEventContributor : IEventHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + await messageSender.SendAsync( + new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel( + context.Message.FromUserName, + new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage( + "感谢您的关注, 点击菜单了解更多."))); + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs new file mode 100644 index 000000000..f85f858a1 --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs @@ -0,0 +1,24 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Work.Common.Messages.Models; +using LINGYUN.Abp.WeChat.Work.Messages; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Work.Messages; +/// +/// 文本消息客服回复 +/// +public class TextMessageReplyContributor : IMessageHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + 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, + }); + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json new file mode 100644 index 000000000..4f753c08e --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json @@ -0,0 +1,249 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//Mysql +// "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;"//Postgres + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "Console": true, + "Http": true, + "Email": true, + "TemporalQuartz": true, + "JavaScriptActivities": true, + "UserTask": true, + "Conductor": true, + "Telnyx": true, + "BlobStoring": true, + "Emailing": true, + "Notification": true, + "Sms": true, + "IM": true, + "PublishWebhook": true, + "Webhooks": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + } + }, + "Server": { + "BaseUrl": "http://127.0.0.1:30000" + } + }, + "Quartz": { + "UsePersistentStore": false, + "Properties": { + "quartz.jobStore.dataSource": "tkm", + "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz", + "quartz.dataSource.tkm.connectionStringName": "Default", + "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz", + "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456", + "quartz.dataSource.tkm.provider": "MySqlConnector", +// "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", +// "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;", +// "quartz.dataSource.tkm.provider": "Npgsql", + "quartz.jobStore.clustered": "true", + "quartz.serializer.type": "json" + } + }, + "Redis": { + "IsEnabled": true, + "Configuration": "127.0.0.1,defaultDatabase=15", + "InstanceName": "LINGYUN.Abp.Application" + }, + "Features": { + "Validation": { + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=13", + "InstanceName": "LINGYUN.Abp.Application" + } + } + }, + "AuthServer": { + "UseOpenIddict": true, + "Authority": "http://127.0.0.1:30001/", + "Audience": "lingyun-abp-application", + "RequireHttpsMetadata": false, + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "IdentityServer": { + "Clients": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + }, + "Lifetime": { + "AuthorizationCode": "00:05:00", + "AccessToken": "14:00:00", + "DeviceCode": "00:10:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00", + "RefreshTokenReuseLeeway": "00:00:30", + "UserCode": "00:10:00" + } + }, + "Identity": { + "Password": { + "RequiredLength": 6, + "RequiredUniqueChars": 0, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + }, + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + }, + "TextTemplating": { + "IsDynamicStoreEnabled": true + }, + "WebhooksManagement": { + "IsDynamicStoreEnabled": true + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "abp.dev.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + }, + "Minio": { + "WithSSL": false, + "BucketName": "blobs", + "EndPoint": "127.0.0.1:19000", + "AccessKey": "ZD43kNpimiJf9mCuomTP", + "SecretKey": "w8IqMgi4Tnz0DGzN8jZ7IJWq7OEdbUnAU0jlZxQK", + "CreateBucketIfNotExists": false + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://127.0.0.1:9200", + "indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json new file mode 100644 index 000000000..ff9beea3e --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json @@ -0,0 +1,89 @@ +{ + "Clock": { + "Kind": "Local" + }, + "Forwarded": { + "ForwardedHeaders": "XForwardedFor,XForwardedProto" + }, + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Json": { + "OutputDateTimeFormat": "yyyy-MM-dd HH:mm:ss", + "InputDateTimeFormats": [ + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-ddTHH:mm:ss" + ] + }, + "AllowedHosts": "*", + "Hosting": { + "BasePath": "" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js new file mode 100644 index 000000000..bec4d578f --- /dev/null +++ b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js @@ -0,0 +1,10 @@ +"use strict"; + +var gulp = require("gulp"), + path = require('path'), + copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js'); + +exports.default = function(done){ + copyResources(path.resolve('./')); + done(); +}; \ No newline at end of file From 42e19cf2fad531825d8356c114a551fdfec1d09b Mon Sep 17 00:00:00 2001 From: feijie Date: Sun, 29 Dec 2024 00:09:43 +0800 Subject: [PATCH 11/29] =?UTF-8?q?=E2=9C=A8=20feat(launchSettings.json):=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=91=BD=E4=BB=A4=E8=A1=8C=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=BB=A5=E5=88=9B=E5=BB=BA=E6=96=B0=E9=A1=B9=E7=9B=AE=E5=B9=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📝 docs(README.zh-CN.md): 添加微服务模板的中文文档说明 📝 docs(README.md): 添加微服务模板的英文文档说明 --- .../Properties/launchSettings.json | 3 +- aspnet-core/templates/content/README.md | 83 +++++++++++++++++++ aspnet-core/templates/content/README.zh-CN.md | 83 +++++++++++++++++++ 3 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 aspnet-core/templates/content/README.md create mode 100644 aspnet-core/templates/content/README.zh-CN.md diff --git a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json index a9b8b5fd2..a10980f84 100644 --- a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json +++ b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/Properties/launchSettings.json @@ -3,7 +3,8 @@ "LINGYUN.Abp.Cli": { "commandName": "Project", //"commandLineArgs": "generate-view -t vben-view -m auditing -o D:\\Projects\\Development\\view-script -url http://127.0.0.1:30000/" - "commandLineArgs": "generate-proxy -t flutter -asp rest-service -u http://127.0.0.1:30000 -m notifications -o D:\\Projects\\Development\\flutter-script -skip-cli-version-check" +// "commandLineArgs": "generate-proxy -t flutter -asp rest-service -u http://127.0.0.1:30000 -m notifications -o D:\\Projects\\Development\\flutter-script -skip-cli-version-check" + "commandLineArgs": "create MyCompanyName.MyProjectName -t lam -pk MyPackageName -o /Users/feijie/Projects/Tests --dbms MySql --cs \"Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None\" --no-random-port" } } } \ No newline at end of file diff --git a/aspnet-core/templates/content/README.md b/aspnet-core/templates/content/README.md new file mode 100644 index 000000000..81638ea3d --- /dev/null +++ b/aspnet-core/templates/content/README.md @@ -0,0 +1,83 @@ +# LINGYUN.Abp.MicroService.Template + +[English](README.md) | [中文](README.zh-CN.md) + +## Introduction + +LINGYUN.Abp.MicroService.Template is a microservice project template based on ABP Framework. This template provides a complete microservice architecture foundation, including necessary project structure and configurations. + +## Features + +- Complete microservice project structure +- Integrated authentication +- Database integration (multiple databases supported) +- Unified configuration management +- Distributed event bus support +- Background job processing + +## How to Use + +### Install Template + +```bash +dotnet new install LINGYUN.Abp.MicroService.Template +``` + +### Create New Project + +```bash +labp create YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +``` + +## How to Run + +After creating your project, you can run it using the following command: + +```bash +dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development" +``` + +For example: +```bash +dotnet run --launch-profile "LY.MicroService.Applications.Single.Development" +``` + +## How to Package and Publish + +1. Clone the Project + +```bash +git clone +cd /aspnet-core/templates/content +``` + +2. Modify Version + Edit `../PackageName.CompanyName.ProjectName.csproj` file, update PackageVersion: + +```xml +8.3.0 +``` + +3. Execute Packaging Script + +```powershell +# Windows PowerShell +.\pack.ps1 + +# PowerShell Core (Windows/Linux/macOS) +pwsh pack.ps1 +``` + +## Supported Databases + +- SqlServer +- MySQL +- PostgreSQL +- Oracle +- SQLite + +## Notes + +- Ensure .NET SDK 8.0 or higher is installed +- Pay attention to NuGet publish address and key when packaging +- Complete testing is recommended before publishing diff --git a/aspnet-core/templates/content/README.zh-CN.md b/aspnet-core/templates/content/README.zh-CN.md new file mode 100644 index 000000000..7ee4451d0 --- /dev/null +++ b/aspnet-core/templates/content/README.zh-CN.md @@ -0,0 +1,83 @@ +# LINGYUN.Abp.MicroService.Template + +[English](README.md) | [中文](README.zh-CN.md) + +## 简介 + +LINGYUN.Abp.MicroService.Template 是一个基于 ABP Framework 的微服务项目模板。此模板提供了一个完整的微服务架构基础,包括必要的项目结构和配置。 + +## 功能特点 + +- 完整的微服务项目结构 +- 集成身份认证 +- 数据库集成(支持多种数据库) +- 统一的配置管理 +- 分布式事件总线支持 +- 后台任务处理 + +## 如何使用 + +### 安装模板 + +```bash +dotnet new install LINGYUN.Abp.MicroService.Template +``` + +### 创建新项目 + +```bash +labp create YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +``` + +## 如何运行 + +创建项目后,您可以使用以下命令运行项目: + +```bash +dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development" +``` + +示例: +```bash +dotnet run --launch-profile "LY.MicroService.Applications.Single.Development" +``` + +## 如何打包发布 + +1. 克隆项目 + +```bash +git clone +cd /aspnet-core/templates/content +``` + +2. 修改版本号 + 编辑 `../PackageName.CompanyName.ProjectName.csproj` 文件,更新 PackageVersion: + +```xml +8.3.0 +``` + +3. 执行打包脚本 + +```powershell +# Windows PowerShell +.\pack.ps1 + +# PowerShell Core (Windows/Linux/macOS) +pwsh pack.ps1 +``` + +## 支持的数据库 + +- SqlServer +- MySQL +- PostgreSQL +- Oracle +- SQLite + +## 注意事项 + +- 确保已安装 .NET SDK 8.0 或更高版本 +- 打包时注意修改 NuGet 发布地址和密钥 +- 建议在发布前进行完整的测试 From 859aebd4a8e65175ba09145f2c5b084d93590aea Mon Sep 17 00:00:00 2001 From: feijie Date: Mon, 30 Dec 2024 00:27:06 +0800 Subject: [PATCH 12/29] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20delete(aspnet-cor?= =?UTF-8?q?e/templates):=20=E5=88=A0=E9=99=A4=E4=B8=8D=E5=86=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E9=A1=B9=E7=9B=AE=E6=A8=A1=E6=9D=BF=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...PackageName.CompanyName.ProjectName.csproj | 30 - .../content/.template.config/template.json | 109 -- .../.template.config/template.zh-Hans.json | 5 - .../templates/content/Directory.Build.props | 13 - .../content/Directory.Packages.props | 490 --------- aspnet-core/templates/content/NuGet.Config | 12 - .../PackageName.CompanyName.ProjectName.sln | 150 --- aspnet-core/templates/content/README.md | 83 -- aspnet-core/templates/content/README.zh-CN.md | 83 -- aspnet-core/templates/content/common.props | 38 - .../templates/content/configureawait.props | 9 - .../.config/dotnet-tools.json | 12 - .../.gitignore | 2 - .../AbpCookieAuthenticationHandler.cs | 89 -- .../BackgroundJobs/NotificationPublishJob.cs | 38 - .../NotificationPublishJobArgs.cs | 22 - .../Controllers/HomeController.cs | 11 - .../Controllers/SettingMergeController.cs | 70 -- .../Controllers/UserSettingMergeController.cs | 45 - .../Dockerfile | 19 - .../Distributed/ChatMessageEventHandler.cs | 59 -- .../Distributed/NotificationEventHandler.cs | 470 --------- .../Distributed/TenantSynchronizer.cs | 53 - .../Distributed/UserCreateEventHandler.cs | 30 - .../Distributed/WebhooksEventHandler.cs | 112 --- .../Local/UserCreateJoinIMEventHandler.cs | 58 -- .../UserCreateSendWelcomeEventHandler.cs | 69 -- .../CustomIdentityResources.cs | 19 - ...rviceApplicationsSingleModule.Configure.cs | 935 ------------------ .../MicroServiceApplicationsSingleModule.cs | 394 -------- ...eSiteCookiesServiceCollectionExtensions.cs | 67 -- .../MultiTenancy/ITenantConfigurationCache.cs | 10 - .../MultiTenancy/TenantConfigurationCache.cs | 59 -- .../TenantConfigurationCacheItem.cs | 19 - ...me.CompanyName.ProjectName.AIO.Host.csproj | 276 ------ .../PersonalInfo/Default.cshtml | 103 -- .../PersonalInfo/Default.js | 28 - .../Pages/Account/EmailConfirm.cshtml | 17 - .../Pages/Account/EmailConfirm.cshtml.cs | 72 -- .../Account/EmailConfirmConfirmation.cshtml | 13 - .../EmailConfirmConfirmation.cshtml.cs | 22 - .../Pages/Account/SendCode.cshtml | 26 - .../Pages/Account/SendCode.cshtml.cs | 125 --- .../Pages/Account/SendEmailConfirm.cshtml | 16 - .../Pages/Account/SendEmailConfirm.cshtml.cs | 73 -- .../Account/TwoFactorSupportedLoginModel.cs | 63 -- .../Pages/Account/UseRecoveryCode.cshtml | 4 - .../Pages/Account/UseRecoveryCode.cshtml.cs | 11 - .../Account/VerifyAuthenticatorCode.cshtml | 26 - .../Account/VerifyAuthenticatorCode.cshtml.cs | 59 -- .../Pages/Account/VerifyCode.cshtml | 29 - .../Pages/Account/VerifyCode.cshtml.cs | 90 -- .../Pages/Index.cshtml | 36 - .../Pages/Index.cshtml.cs | 11 - .../Pages/_ViewImports.cshtml | 4 - .../Program.cs | 82 -- .../Properties/launchSettings.json | 30 - .../TenantHeaderParamter.cs | 35 - .../Messages/TextMessageReplyContributor.cs | 21 - .../Messages/UserSubscribeEventContributor.cs | 21 - .../Messages/TextMessageReplyContributor.cs | 24 - .../appsettings.Development.json | 249 ----- .../appsettings.json | 89 -- .../gulpfile.js | 10 - .../DbMigratorHostedService.cs | 53 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ....CompanyName.ProjectName.DbMigrator.csproj | 42 - ...eCompanyNameProjectNameDbMigratorModule.cs | 13 - .../Program.cs | 40 - .../appsettings.Development.json | 147 --- .../appsettings.json | 80 -- .../Controllers/HomeController.cs | 12 - .../Dockerfile | 57 -- ...ompanyName.ProjectName.HttpApi.Host.csproj | 76 -- .../Program.cs | 65 -- .../ProjectNameHttpApiHostModule.Configure.cs | 445 --------- .../ProjectNameHttpApiHostModule.cs | 127 --- .../Properties/launchSettings.json | 28 - .../TenantHeaderParamter.cs | 31 - .../appsettings.Development.json | 153 --- .../appsettings.json | 88 -- .../dapr.sh | 1 - .../generate-proxy.sh | 2 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...e.ProjectName.Application.Contracts.csproj | 27 - .../ProjectNameFeatureDefinitionProvider.cs | 18 - .../Features/ProjectNameFeatureNames.cs | 6 - .../IProjectNameDynamicQueryableAppService.cs | 10 - ...ProjectNamePermissionDefinitionProvider.cs | 22 - .../Permissions/ProjectNamePermissions.cs | 8 - .../ProjectNameApplicationContractsModule.cs | 17 - .../ProjectNameRemoteServiceConsts.cs | 7 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...CompanyName.ProjectName.Application.csproj | 26 - .../ProjectName/ProjectNameAppServiceBase.cs | 13 - .../ProjectNameApplicationMapperProfile.cs | 10 - .../ProjectNameApplicationModule.cs | 27 - ...ojectNameDynamicQueryableAppServiceBase.cs | 19 - .../Expressions/ExpressionFuncExtensions.cs | 32 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...CompanyName.ProjectName.Dapr.Client.csproj | 19 - .../ProjectNameDaprClientModule.cs | 18 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...mpanyName.ProjectName.Domain.Shared.csproj | 30 - .../Localization/ProjectNameResource.cs | 8 - .../Localization/Resources/en.json | 8 - .../Localization/Resources/zh-Hans.json | 8 - ...ProjectNameModuleExtensionConfiguration.cs | 16 - ...ensionConfigurationDictionaryExtensions.cs | 19 - .../ProjectNameModuleExtensionConsts.cs | 11 - .../ProjectNameDomainSharedModule.cs | 32 - .../ProjectName/ProjectNameErrorCodes.cs | 6 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...Name.CompanyName.ProjectName.Domain.csproj | 27 - .../IProjectNameBasicRepository.cs | 54 - .../ProjectName/ProjectNameDbProperties.cs | 11 - .../ProjectNameDomainMapperProfile.cs | 11 - .../ProjectName/ProjectNameDomainModule.cs | 45 - .../ProjectNameSettingDefinitionProvider.cs | 10 - .../Settings/ProjectNameSettings.cs | 6 - .../Expressions/ExpressionFuncExtensions.cs | 32 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...ame.ProjectName.EntityFrameworkCore.csproj | 37 - .../EfCoreProjectNameRepository.cs | 77 -- .../IProjectNameDbContext.cs | 9 - .../ProjectNameDbContext.cs | 21 - .../ProjectNameDbContextFactory.cs | 49 - ...ectNameDbContextModelCreatingExtensions.cs | 21 - .../ProjectNameDbMigrationEventHandler.cs | 36 - .../ProjectNameDbMigrationService.cs | 58 -- .../ProjectNameEfCoreQueryableExtensions.cs | 6 - .../ProjectNameEntityFrameworkCoreModule.cs | 76 -- ...ectNameModelBuilderConfigurationOptions.cs | 17 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...panyName.ProjectName.HttpApi.Client.csproj | 24 - .../ProjectNameHttpApiClientModule.cs | 18 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...ame.CompanyName.ProjectName.HttpApi.csproj | 25 - .../ProjectName/ProjectNameControllerBase.cs | 12 - ...ojectNameDynamicQueryableControllerBase.cs | 17 - .../ProjectName/ProjectNameHttpApiModule.cs | 42 - .../FodyWeavers.xml | 3 - .../FodyWeavers.xsd | 30 - ...yName.ProjectName.SettingManagement.csproj | 27 - .../IProjectNameSettingAppService.cs | 7 - .../ProjectNameSettingAppService.cs | 106 -- .../ProjectNameSettingController.cs | 69 -- .../ProjectNameSettingManagementModule.cs | 22 - ...yName.ProjectName.Application.Tests.csproj | 18 - .../ProjectNameApplicationTestBase.cs | 5 - .../ProjectNameApplicationTestModule.cs | 11 - ...ompanyName.ProjectName.Domain.Tests.csproj | 18 - .../ProjectName/ProjectNameDomainTestBase.cs | 5 - .../ProjectNameDomainTestModule.cs | 11 - ...ojectName.EntityFrameworkCore.Tests.csproj | 19 - .../ProjectNameEntityFrameworkCoreTestBase.cs | 5 - ...rojectNameEntityFrameworkCoreTestModule.cs | 38 - ...me.CompanyName.ProjectName.TestBase.csproj | 23 - .../ProjectName/ProjectNameTestBase.cs | 58 -- .../ProjectName/ProjectNameTestBaseModule.cs | 24 - 169 files changed, 8763 deletions(-) delete mode 100644 aspnet-core/templates/PackageName.CompanyName.ProjectName.csproj delete mode 100644 aspnet-core/templates/content/.template.config/template.json delete mode 100644 aspnet-core/templates/content/.template.config/template.zh-Hans.json delete mode 100644 aspnet-core/templates/content/Directory.Build.props delete mode 100644 aspnet-core/templates/content/Directory.Packages.props delete mode 100644 aspnet-core/templates/content/NuGet.Config delete mode 100644 aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln delete mode 100644 aspnet-core/templates/content/README.md delete mode 100644 aspnet-core/templates/content/README.zh-CN.md delete mode 100644 aspnet-core/templates/content/common.props delete mode 100644 aspnet-core/templates/content/configureawait.props delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh delete mode 100644 aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs delete mode 100644 aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs delete mode 100644 aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs diff --git a/aspnet-core/templates/PackageName.CompanyName.ProjectName.csproj b/aspnet-core/templates/PackageName.CompanyName.ProjectName.csproj deleted file mode 100644 index cceabf72e..000000000 --- a/aspnet-core/templates/PackageName.CompanyName.ProjectName.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - net8.0 - true - LINGYUN.Abp.MicroService.Templates - 8.3.0 - colin.in@foxmail.com - Abp framework micro-service template - MIT - false - https://github.com/colinin/abp-next-admin - micro webapi cloud - Template - git - https://github.com/colinin/abp-next-admin - true - true - true - true - False - False - - - - - true - content - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/.template.config/template.json b/aspnet-core/templates/content/.template.config/template.json deleted file mode 100644 index 132f70183..000000000 --- a/aspnet-core/templates/content/.template.config/template.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/template", - "author": "colin.in@foxmail.com", - "classifications": ["micro", "webapi", "cloud"], - "name": "LINGYUN.Abp.MicroService", - "identity": "LINGYUN.Abp.MicroService", - "description": "Abp framework micro-service template", - "groupIdentity": "LINGYUN.Abp.Application", - "shortName": "lam", - "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\")" - } - } -} diff --git a/aspnet-core/templates/content/.template.config/template.zh-Hans.json b/aspnet-core/templates/content/.template.config/template.zh-Hans.json deleted file mode 100644 index f0339e4e4..000000000 --- a/aspnet-core/templates/content/.template.config/template.zh-Hans.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "description": "适用于abp框架的微服务模板项目", - "symbols/AuthenticationScheme/description": "认证服务体系, 可选项为: IdentityServer4、OpenIddict, 默认使用IdentityServer4.", - "symbols/DatabaseManagement/description": "数据库管理提供者, 可选项为: SqlServer、MySQL、Sqlite、Oracle、OracleDevart、PostgreSql, 默认使用MySQL." -} diff --git a/aspnet-core/templates/content/Directory.Build.props b/aspnet-core/templates/content/Directory.Build.props deleted file mode 100644 index a9ca45ada..000000000 --- a/aspnet-core/templates/content/Directory.Build.props +++ /dev/null @@ -1,13 +0,0 @@ - - - true - - - - - all - runtime; build; native; contentfiles; analyzers - - - - diff --git a/aspnet-core/templates/content/Directory.Packages.props b/aspnet-core/templates/content/Directory.Packages.props deleted file mode 100644 index 433f06afb..000000000 --- a/aspnet-core/templates/content/Directory.Packages.props +++ /dev/null @@ -1,490 +0,0 @@ - - - 8.2.0 - 2.14.1 - 8.3.0 - 8.3.0 - 8.0.0 - 8.0.0 - 8.0.0 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/NuGet.Config b/aspnet-core/templates/content/NuGet.Config deleted file mode 100644 index ddde6944c..000000000 --- a/aspnet-core/templates/content/NuGet.Config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln b/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln deleted file mode 100644 index 8d3a5d224..000000000 --- a/aspnet-core/templates/content/PackageName.CompanyName.ProjectName.sln +++ /dev/null @@ -1,150 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4B0AD527-99B3-49A9-8A45-FD8671F8BE4D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.HttpApi.Host", "host\PackageName.CompanyName.ProjectName.HttpApi.Host\PackageName.CompanyName.ProjectName.HttpApi.Host.csproj", "{31E33CE2-71D3-43FF-9A30-2DCC82C607AE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Solution Items", ".Solution Items", "{C9675742-7986-4BC1-9781-FD1C3C5B6287}" - ProjectSection(SolutionItems) = preProject - common.props = common.props - configureawait.props = configureawait.props - Directory.Build.props = Directory.Build.props - Directory.Packages.props = Directory.Packages.props - NuGet.Config = NuGet.Config - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{4786387C-C1C5-46F8-806F-EBC54DB0A4FA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A9CB1547-1C2C-4A23-82EC-C834C1626E0A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Application.Tests", "tests\PackageName.CompanyName.ProjectName.Application.Tests\PackageName.CompanyName.ProjectName.Application.Tests.csproj", "{9262FE7A-76B2-424F-8C34-AFA1D95D7E5A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Domain.Tests", "tests\PackageName.CompanyName.ProjectName.Domain.Tests\PackageName.CompanyName.ProjectName.Domain.Tests.csproj", "{A0D1F8A4-3494-4E26-9E2D-DB874B93DBCE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests", "tests\PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests\PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj", "{0B2E1C9E-092D-4E5F-BE9F-5506E689FC85}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.TestBase", "tests\PackageName.CompanyName.ProjectName.TestBase\PackageName.CompanyName.ProjectName.TestBase.csproj", "{4A9D43A2-D08B-40E8-9C74-F2B95BF81AED}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.DbMigrator", "host\PackageName.CompanyName.ProjectName.DbMigrator\PackageName.CompanyName.ProjectName.DbMigrator.csproj", "{F6EE5BCD-69C7-4C8A-8B45-251AFE2BB01E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migrations", "migrations", "{2BF87FAA-69E7-486E-9123-1F407A2BB633}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Domain.Shared", "src\PackageName.CompanyName.ProjectName.Domain.Shared\PackageName.CompanyName.ProjectName.Domain.Shared.csproj", "{77090F97-BD80-4469-842F-F5769CF849E9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Domain", "src\PackageName.CompanyName.ProjectName.Domain\PackageName.CompanyName.ProjectName.Domain.csproj", "{DF2CCF03-95D5-4BE4-8B32-742818C56F15}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Application.Contracts", "src\PackageName.CompanyName.ProjectName.Application.Contracts\PackageName.CompanyName.ProjectName.Application.Contracts.csproj", "{54FB9929-7D9C-40FC-A0D0-94ACBA37D20E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Application", "src\PackageName.CompanyName.ProjectName.Application\PackageName.CompanyName.ProjectName.Application.csproj", "{F2A6182F-BCB9-4C80-947C-0A2ED1B6BFDB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.Dapr.Client", "src\PackageName.CompanyName.ProjectName.Dapr.Client\PackageName.CompanyName.ProjectName.Dapr.Client.csproj", "{B69F04FF-8505-49F6-9B60-BB800846C87C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.EntityFrameworkCore", "src\PackageName.CompanyName.ProjectName.EntityFrameworkCore\PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj", "{09CA7186-DBA7-4428-A1ED-31292AC02050}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.HttpApi", "src\PackageName.CompanyName.ProjectName.HttpApi\PackageName.CompanyName.ProjectName.HttpApi.csproj", "{FDB3A3E9-C072-438D-8B8D-2AA957C1167F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.HttpApi.Client", "src\PackageName.CompanyName.ProjectName.HttpApi.Client\PackageName.CompanyName.ProjectName.HttpApi.Client.csproj", "{8CE7C515-CD78-42D4-A9D7-39D217A3D046}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PackageName.CompanyName.ProjectName.SettingManagement", "src\PackageName.CompanyName.ProjectName.SettingManagement\PackageName.CompanyName.ProjectName.SettingManagement.csproj", "{CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageName.CompanyName.ProjectName.AIO.Host", "host\PackageName.CompanyName.ProjectName.AIO.Host\PackageName.CompanyName.ProjectName.AIO.Host.csproj", "{26F1E2F7-3B0E-4333-9E66-EFE0D113386B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {31E33CE2-71D3-43FF-9A30-2DCC82C607AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {31E33CE2-71D3-43FF-9A30-2DCC82C607AE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {31E33CE2-71D3-43FF-9A30-2DCC82C607AE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {31E33CE2-71D3-43FF-9A30-2DCC82C607AE}.Release|Any CPU.Build.0 = Release|Any CPU - {9262FE7A-76B2-424F-8C34-AFA1D95D7E5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9262FE7A-76B2-424F-8C34-AFA1D95D7E5A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9262FE7A-76B2-424F-8C34-AFA1D95D7E5A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9262FE7A-76B2-424F-8C34-AFA1D95D7E5A}.Release|Any CPU.Build.0 = Release|Any CPU - {A0D1F8A4-3494-4E26-9E2D-DB874B93DBCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A0D1F8A4-3494-4E26-9E2D-DB874B93DBCE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A0D1F8A4-3494-4E26-9E2D-DB874B93DBCE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A0D1F8A4-3494-4E26-9E2D-DB874B93DBCE}.Release|Any CPU.Build.0 = Release|Any CPU - {0B2E1C9E-092D-4E5F-BE9F-5506E689FC85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0B2E1C9E-092D-4E5F-BE9F-5506E689FC85}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0B2E1C9E-092D-4E5F-BE9F-5506E689FC85}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0B2E1C9E-092D-4E5F-BE9F-5506E689FC85}.Release|Any CPU.Build.0 = Release|Any CPU - {4A9D43A2-D08B-40E8-9C74-F2B95BF81AED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A9D43A2-D08B-40E8-9C74-F2B95BF81AED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A9D43A2-D08B-40E8-9C74-F2B95BF81AED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A9D43A2-D08B-40E8-9C74-F2B95BF81AED}.Release|Any CPU.Build.0 = Release|Any CPU - {F6EE5BCD-69C7-4C8A-8B45-251AFE2BB01E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F6EE5BCD-69C7-4C8A-8B45-251AFE2BB01E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F6EE5BCD-69C7-4C8A-8B45-251AFE2BB01E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F6EE5BCD-69C7-4C8A-8B45-251AFE2BB01E}.Release|Any CPU.Build.0 = Release|Any CPU - {77090F97-BD80-4469-842F-F5769CF849E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77090F97-BD80-4469-842F-F5769CF849E9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {77090F97-BD80-4469-842F-F5769CF849E9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {77090F97-BD80-4469-842F-F5769CF849E9}.Release|Any CPU.Build.0 = Release|Any CPU - {DF2CCF03-95D5-4BE4-8B32-742818C56F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DF2CCF03-95D5-4BE4-8B32-742818C56F15}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DF2CCF03-95D5-4BE4-8B32-742818C56F15}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DF2CCF03-95D5-4BE4-8B32-742818C56F15}.Release|Any CPU.Build.0 = Release|Any CPU - {54FB9929-7D9C-40FC-A0D0-94ACBA37D20E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {54FB9929-7D9C-40FC-A0D0-94ACBA37D20E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {54FB9929-7D9C-40FC-A0D0-94ACBA37D20E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {54FB9929-7D9C-40FC-A0D0-94ACBA37D20E}.Release|Any CPU.Build.0 = Release|Any CPU - {F2A6182F-BCB9-4C80-947C-0A2ED1B6BFDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2A6182F-BCB9-4C80-947C-0A2ED1B6BFDB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2A6182F-BCB9-4C80-947C-0A2ED1B6BFDB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2A6182F-BCB9-4C80-947C-0A2ED1B6BFDB}.Release|Any CPU.Build.0 = Release|Any CPU - {B69F04FF-8505-49F6-9B60-BB800846C87C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B69F04FF-8505-49F6-9B60-BB800846C87C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B69F04FF-8505-49F6-9B60-BB800846C87C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B69F04FF-8505-49F6-9B60-BB800846C87C}.Release|Any CPU.Build.0 = Release|Any CPU - {09CA7186-DBA7-4428-A1ED-31292AC02050}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {09CA7186-DBA7-4428-A1ED-31292AC02050}.Debug|Any CPU.Build.0 = Debug|Any CPU - {09CA7186-DBA7-4428-A1ED-31292AC02050}.Release|Any CPU.ActiveCfg = Release|Any CPU - {09CA7186-DBA7-4428-A1ED-31292AC02050}.Release|Any CPU.Build.0 = Release|Any CPU - {FDB3A3E9-C072-438D-8B8D-2AA957C1167F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FDB3A3E9-C072-438D-8B8D-2AA957C1167F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FDB3A3E9-C072-438D-8B8D-2AA957C1167F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FDB3A3E9-C072-438D-8B8D-2AA957C1167F}.Release|Any CPU.Build.0 = Release|Any CPU - {8CE7C515-CD78-42D4-A9D7-39D217A3D046}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8CE7C515-CD78-42D4-A9D7-39D217A3D046}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CE7C515-CD78-42D4-A9D7-39D217A3D046}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8CE7C515-CD78-42D4-A9D7-39D217A3D046}.Release|Any CPU.Build.0 = Release|Any CPU - {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B}.Release|Any CPU.Build.0 = Release|Any CPU - {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {26F1E2F7-3B0E-4333-9E66-EFE0D113386B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {31E33CE2-71D3-43FF-9A30-2DCC82C607AE} = {4786387C-C1C5-46F8-806F-EBC54DB0A4FA} - {9262FE7A-76B2-424F-8C34-AFA1D95D7E5A} = {A9CB1547-1C2C-4A23-82EC-C834C1626E0A} - {A0D1F8A4-3494-4E26-9E2D-DB874B93DBCE} = {A9CB1547-1C2C-4A23-82EC-C834C1626E0A} - {0B2E1C9E-092D-4E5F-BE9F-5506E689FC85} = {A9CB1547-1C2C-4A23-82EC-C834C1626E0A} - {4A9D43A2-D08B-40E8-9C74-F2B95BF81AED} = {A9CB1547-1C2C-4A23-82EC-C834C1626E0A} - {F6EE5BCD-69C7-4C8A-8B45-251AFE2BB01E} = {2BF87FAA-69E7-486E-9123-1F407A2BB633} - {77090F97-BD80-4469-842F-F5769CF849E9} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {DF2CCF03-95D5-4BE4-8B32-742818C56F15} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {54FB9929-7D9C-40FC-A0D0-94ACBA37D20E} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {F2A6182F-BCB9-4C80-947C-0A2ED1B6BFDB} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {B69F04FF-8505-49F6-9B60-BB800846C87C} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {09CA7186-DBA7-4428-A1ED-31292AC02050} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {FDB3A3E9-C072-438D-8B8D-2AA957C1167F} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {8CE7C515-CD78-42D4-A9D7-39D217A3D046} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {CAEB3435-A332-4FFA-BE5F-4E386FA8B19B} = {4B0AD527-99B3-49A9-8A45-FD8671F8BE4D} - {26F1E2F7-3B0E-4333-9E66-EFE0D113386B} = {4786387C-C1C5-46F8-806F-EBC54DB0A4FA} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {62C0F185-E2C2-46A2-B4B2-5E703E25849E} - EndGlobalSection -EndGlobal diff --git a/aspnet-core/templates/content/README.md b/aspnet-core/templates/content/README.md deleted file mode 100644 index 81638ea3d..000000000 --- a/aspnet-core/templates/content/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# LINGYUN.Abp.MicroService.Template - -[English](README.md) | [中文](README.zh-CN.md) - -## Introduction - -LINGYUN.Abp.MicroService.Template is a microservice project template based on ABP Framework. This template provides a complete microservice architecture foundation, including necessary project structure and configurations. - -## Features - -- Complete microservice project structure -- Integrated authentication -- Database integration (multiple databases supported) -- Unified configuration management -- Distributed event bus support -- Background job processing - -## How to Use - -### Install Template - -```bash -dotnet new install LINGYUN.Abp.MicroService.Template -``` - -### Create New Project - -```bash -labp create YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port -``` - -## How to Run - -After creating your project, you can run it using the following command: - -```bash -dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development" -``` - -For example: -```bash -dotnet run --launch-profile "LY.MicroService.Applications.Single.Development" -``` - -## How to Package and Publish - -1. Clone the Project - -```bash -git clone -cd /aspnet-core/templates/content -``` - -2. Modify Version - Edit `../PackageName.CompanyName.ProjectName.csproj` file, update PackageVersion: - -```xml -8.3.0 -``` - -3. Execute Packaging Script - -```powershell -# Windows PowerShell -.\pack.ps1 - -# PowerShell Core (Windows/Linux/macOS) -pwsh pack.ps1 -``` - -## Supported Databases - -- SqlServer -- MySQL -- PostgreSQL -- Oracle -- SQLite - -## Notes - -- Ensure .NET SDK 8.0 or higher is installed -- Pay attention to NuGet publish address and key when packaging -- Complete testing is recommended before publishing diff --git a/aspnet-core/templates/content/README.zh-CN.md b/aspnet-core/templates/content/README.zh-CN.md deleted file mode 100644 index 7ee4451d0..000000000 --- a/aspnet-core/templates/content/README.zh-CN.md +++ /dev/null @@ -1,83 +0,0 @@ -# LINGYUN.Abp.MicroService.Template - -[English](README.md) | [中文](README.zh-CN.md) - -## 简介 - -LINGYUN.Abp.MicroService.Template 是一个基于 ABP Framework 的微服务项目模板。此模板提供了一个完整的微服务架构基础,包括必要的项目结构和配置。 - -## 功能特点 - -- 完整的微服务项目结构 -- 集成身份认证 -- 数据库集成(支持多种数据库) -- 统一的配置管理 -- 分布式事件总线支持 -- 后台任务处理 - -## 如何使用 - -### 安装模板 - -```bash -dotnet new install LINGYUN.Abp.MicroService.Template -``` - -### 创建新项目 - -```bash -labp create YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port -``` - -## 如何运行 - -创建项目后,您可以使用以下命令运行项目: - -```bash -dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development" -``` - -示例: -```bash -dotnet run --launch-profile "LY.MicroService.Applications.Single.Development" -``` - -## 如何打包发布 - -1. 克隆项目 - -```bash -git clone -cd /aspnet-core/templates/content -``` - -2. 修改版本号 - 编辑 `../PackageName.CompanyName.ProjectName.csproj` 文件,更新 PackageVersion: - -```xml -8.3.0 -``` - -3. 执行打包脚本 - -```powershell -# Windows PowerShell -.\pack.ps1 - -# PowerShell Core (Windows/Linux/macOS) -pwsh pack.ps1 -``` - -## 支持的数据库 - -- SqlServer -- MySQL -- PostgreSQL -- Oracle -- SQLite - -## 注意事项 - -- 确保已安装 .NET SDK 8.0 或更高版本 -- 打包时注意修改 NuGet 发布地址和密钥 -- 建议在发布前进行完整的测试 diff --git a/aspnet-core/templates/content/common.props b/aspnet-core/templates/content/common.props deleted file mode 100644 index c299ae39b..000000000 --- a/aspnet-core/templates/content/common.props +++ /dev/null @@ -1,38 +0,0 @@ - - - latest - 8.2.1 - colin - $(NoWarn);CS1591;CS0436;CS8618;NU1803 - https://github.com/colinin/abp-next-admin - $(SolutionDir)LocalNuget - 8.2.1 - MIT - git - https://github.com/colinin/abp-next-admin - true - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)LocalNuget - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/configureawait.props b/aspnet-core/templates/content/configureawait.props deleted file mode 100644 index 3caa88c04..000000000 --- a/aspnet-core/templates/content/configureawait.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - All - runtime; build; native; contentfiles; analyzers - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json deleted file mode 100644 index 6b93cca86..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "dotnet-ef": { - "version": "7.0.3", - "commands": [ - "dotnet-ef" - ] - } - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore deleted file mode 100644 index 7b6f60857..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -wwwroot -package*.json \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs deleted file mode 100644 index 34517090f..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs +++ /dev/null @@ -1,89 +0,0 @@ -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 options, - ILoggerFactory logger, - UrlEncoder encoder) : base(options, logger, encoder) - { - } - - public AbpCookieAuthenticationHandler( - IOptionsMonitor 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; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs deleted file mode 100644 index c9db9977a..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs +++ /dev/null @@ -1,38 +0,0 @@ -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, ITransientDependency -{ - protected AbpNotificationsPublishOptions Options { get; } - protected IServiceScopeFactory ServiceScopeFactory { get; } - protected INotificationDataSerializer NotificationDataSerializer { get; } - public NotificationPublishJob( - IOptions 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(); - var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); - notification.Data = NotificationDataSerializer.Serialize(notification.Data); - - await publishProvider.PublishAsync(notification, args.UserIdentifiers); - } - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs deleted file mode 100644 index e5f077d65..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs +++ /dev/null @@ -1,22 +0,0 @@ -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 UserIdentifiers { get; set; } - public NotificationPublishJobArgs() - { - UserIdentifiers = new List(); - } - public NotificationPublishJobArgs(long id, string providerType, List userIdentifiers, Guid? tenantId = null) - { - NotificationId = id; - ProviderType = providerType; - UserIdentifiers = userIdentifiers; - TenantId = tenantId; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs deleted file mode 100644 index e693a0917..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; - -public class HomeController : Controller -{ - public IActionResult Index() - { - return Redirect("/swagger"); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs deleted file mode 100644 index 11e91bd88..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs +++ /dev/null @@ -1,70 +0,0 @@ -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 mergeOptions) - : base(settingAppService, settingTestAppService) - { - _mergeOptions = mergeOptions.Value; - } - - [HttpGet] - [Route("by-current-tenant")] - public async override Task GetAllForCurrentTenantAsync() - { - var result = new SettingGroupResult(); - var markTypeMap = new List - { - typeof(SettingMergeController), - }; - foreach (var serviceType in _mergeOptions.GlobalSettingProviders - .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) - { - var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); - 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 GetAllForGlobalAsync() - { - var result = new SettingGroupResult(); - var markTypeMap = new List - { - typeof(SettingMergeController), - }; - foreach (var serviceType in _mergeOptions.GlobalSettingProviders - .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) - { - var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); - var currentResult = await settingService.GetAllForGlobalAsync(); - foreach (var group in currentResult.Items) - { - result.AddGroup(group); - } - markTypeMap.Add(serviceType); - } - - return result; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs deleted file mode 100644 index 5091a8a5e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs +++ /dev/null @@ -1,45 +0,0 @@ -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 mergeOptions) - : base(service) - { - _mergeOptions = mergeOptions.Value; - } - - [HttpGet] - [Route("by-current-user")] - public async override Task GetAllForCurrentUserAsync() - { - var result = new SettingGroupResult(); - var markTypeMap = new List - { - typeof(UserSettingMergeController), - }; - foreach (var serviceType in _mergeOptions.UserSettingProviders - .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) - { - var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); - var currentResult = await settingService.GetAllForCurrentUserAsync(); - foreach (var group in currentResult.Items) - { - result.AddGroup(group); - } - markTypeMap.Add(serviceType); - } - - return result; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile deleted file mode 100644 index aee09fd66..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -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"] diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs deleted file mode 100644 index a08702a0a..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs +++ /dev/null @@ -1,59 +0,0 @@ -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>, ITransientDependency - { - /// - /// Reference to . - /// - public ILogger Logger { get; set; } - /// - /// Reference to . - /// - protected AbpIMOptions Options { get; } - - protected IMessageStore MessageStore { get; } - protected IMessageBlocker MessageBlocker { get; } - protected IMessageSenderProviderManager MessageSenderProviderManager { get; } - - public ChatMessageEventHandler( - IOptions options, - IMessageStore messageStore, - IMessageBlocker messageBlocker, - IMessageSenderProviderManager messageSenderProviderManager) - { - Options = options.Value; - MessageStore = messageStore; - MessageBlocker = messageBlocker; - MessageSenderProviderManager = messageSenderProviderManager; - - Logger = NullLogger.Instance; - } - - public async virtual Task HandleEventAsync(RealTimeEto 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); - } - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs deleted file mode 100644 index cb871c6ef..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs +++ /dev/null @@ -1,470 +0,0 @@ -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 -{ - /// - /// 订阅通知发布事件,统一发布消息 - /// - /// - /// 作用在于SignalR客户端只会与一台服务器建立连接, - /// 只有启用了SignlR服务端的才能真正将消息发布到客户端 - /// - public class NotificationEventHandler : - IDistributedEventHandler>, - IDistributedEventHandler>, - ITransientDependency - { - /// - /// Reference to . - /// - public ILogger Logger { get; set; } - /// - /// Reference to . - /// - protected AbpNotificationsPublishOptions Options { get; } - /// - /// Reference to . - /// - protected ICurrentTenant CurrentTenant { get; } - /// - /// Reference to . - /// - protected ITenantConfigurationCache TenantConfigurationCache { get; } - /// - /// Reference to . - /// - protected IJsonSerializer JsonSerializer { get; } - /// - /// Reference to . - /// - protected IBackgroundJobManager BackgroundJobManager { get; } - /// - /// Reference to . - /// - protected ITemplateRenderer TemplateRenderer { get; } - /// - /// Reference to . - /// - protected INotificationStore NotificationStore { get; } - /// - /// Reference to . - /// - protected IStringLocalizerFactory StringLocalizerFactory { get; } - /// - /// Reference to . - /// - protected INotificationDataSerializer NotificationDataSerializer { get; } - /// - /// Reference to . - /// - protected INotificationDefinitionManager NotificationDefinitionManager { get; } - /// - /// Reference to . - /// - protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } - /// - /// Reference to . - /// - protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } - - /// - /// Initializes a new instance of the class. - /// - public NotificationEventHandler( - ICurrentTenant currentTenant, - ITenantConfigurationCache tenantConfigurationCache, - IJsonSerializer jsonSerializer, - ITemplateRenderer templateRenderer, - IBackgroundJobManager backgroundJobManager, - IStringLocalizerFactory stringLocalizerFactory, - IOptions 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.Instance; - } - - [UnitOfWork] - public async virtual Task HandleEventAsync(NotificationEto 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 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 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 - { - // 模板不支持 $ 字符, 改为普通关键字 - { 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 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); - } - } - } - } - /// - /// 获取用户订阅列表 - /// - /// 通知名称 - /// 接收用户列表 - /// 租户标识 - /// 用户订阅列表 - protected async Task> GerSubscriptionUsersAsync( - string notificationName, - IEnumerable 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(); - } - /// - /// 持久化通知并返回订阅用户列表 - /// - /// 通知实体 - /// 订阅用户列表 - /// 通知发送提供者 - /// 返回订阅者列表 - protected async Task PersistentNotificationAsync( - NotificationInfo notificationInfo, - IEnumerable subscriptionUsers, - IEnumerable 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); - } - } - } - /// - /// 发布订阅者通知 - /// - /// 通知发布者 - /// 通知信息 - /// 订阅用户列表 - /// - protected async Task PublishToSubscriberAsync( - INotificationPublishProvider provider, - NotificationInfo notificationInfo, - IEnumerable 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); - } - } - /// - /// 处理失败的消息进入后台队列 - /// - /// - /// 注: 如果入队失败,消息将被丢弃. - /// - /// - /// - /// - /// - protected async Task ProcessingFailedToQueueAsync( - INotificationPublishProvider provider, - NotificationInfo notificationInfo, - IEnumerable 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); - } - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs deleted file mode 100644 index 3e07d5be9..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs +++ /dev/null @@ -1,53 +0,0 @@ -using LINGYUN.Abp.Saas.Tenants; -using PackageName.CompanyName.ProjectName.AIO.Host.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 PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed -{ - public class TenantSynchronizer : - IDistributedEventHandler>, - IDistributedEventHandler>, - IDistributedEventHandler>, - IDistributedEventHandler, - 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 eventData) - { - await TenantConfigurationCache.RefreshAsync(); - - await DataSeeder.SeedAsync(eventData.Entity.Id); - } - - public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) - { - await TenantConfigurationCache.RefreshAsync(); - } - - public async virtual Task HandleEventAsync(EntityDeletedEto eventData) - { - await TenantConfigurationCache.RefreshAsync(); - } - - public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) - { - await TenantConfigurationCache.RefreshAsync(); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs deleted file mode 100644 index ee5ab700b..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs +++ /dev/null @@ -1,30 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed -{ - public class UserCreateEventHandler : IDistributedEventHandler>, ITransientDependency - { - private readonly ILocalEventBus _localEventBus; - public UserCreateEventHandler( - ILocalEventBus localEventBus) - { - _localEventBus = localEventBus; - } - /// - /// 接收添加用户事件,发布本地事件 - /// - /// - /// - public async Task HandleEventAsync(EntityCreatedEto eventData) - { - var localUserCreateEventData = new EntityCreatedEventData(eventData.Entity); - - await _localEventBus.PublishAsync(localUserCreateEventData); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs deleted file mode 100644 index eeb0fcdb7..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs +++ /dev/null @@ -1,112 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed; - -public class WebhooksEventHandler : - IDistributedEventHandler, - 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 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 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; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs deleted file mode 100644 index 2b78e5841..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs +++ /dev/null @@ -1,58 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Local -{ - public class UserCreateJoinIMEventHandler : ILocalEventHandler>, ITransientDependency - { - private readonly IChatDataSeeder _chatDataSeeder; - private readonly INotificationSubscriptionManager _notificationSubscriptionManager; - public UserCreateJoinIMEventHandler( - IChatDataSeeder chatDataSeeder, - INotificationSubscriptionManager notificationSubscriptionManager) - { - _chatDataSeeder = chatDataSeeder; - _notificationSubscriptionManager = notificationSubscriptionManager; - } - /// - /// 接收添加用户事件,初始化IM用户种子 - /// - /// - /// - [UnitOfWork] - public async virtual Task HandleEventAsync(EntityCreatedEventData 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); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs deleted file mode 100644 index 8176df498..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs +++ /dev/null @@ -1,69 +0,0 @@ -using LINGYUN.Abp.Notifications; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities.Events; -using Volo.Abp.EventBus; -using Volo.Abp.Users; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Local -{ - public class UserCreateSendWelcomeEventHandler : ILocalEventHandler>, ITransientDependency - { - private readonly INotificationSender _notificationSender; - private readonly INotificationSubscriptionManager _notificationSubscriptionManager; - public UserCreateSendWelcomeEventHandler( - INotificationSender notificationSender, - INotificationSubscriptionManager notificationSubscriptionManager - ) - { - _notificationSender = notificationSender; - _notificationSubscriptionManager = notificationSubscriptionManager; - } - - public async Task HandleEventAsync(EntityCreatedEventData 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 - { - { "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); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs deleted file mode 100644 index 99fce8c22..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LINGYUN.Abp.Identity; -using IdentityServer4.Models; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.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 }; - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs deleted file mode 100644 index cbc4e883a..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs +++ /dev/null @@ -1,935 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection; -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 PackageName.CompanyName.ProjectName.AIO.Host.Authentication; -using PackageName.CompanyName.ProjectName.AIO.Host.IdentityResources; -using PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; -using Quartz; -using StackExchange.Redis; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -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 PackageName.CompanyName.ProjectName.AIO.Host; - -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(options => - { - // 以开放端口区别,应在0-31之间 - options.SnowflakeIdOptions.WorkerId = 1; - options.SnowflakeIdOptions.WorkerIdBits = 5; - options.SnowflakeIdOptions.DatacenterId = 1; - }); - - if (configuration.GetValue("App:ShowPii")) - { - IdentityModelEventSource.ShowPII = true; - } - } - - private void PreConfigureAuthServer(IConfiguration configuration) - { - PreConfigure(builder => - { - builder.AddValidation(options => - { - //options.AddAudiences("lingyun-abp-application"); - - options.UseLocalServer(); - - options.UseAspNetCore(); - - options.UseDataProtection(); - }); - }); - } - - private void PreConfigureIdentity() - { - PreConfigure(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("AuthServer:UseOpenIddict")) - { - PreConfigure(options => - { - //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html - options.AddDevelopmentEncryptionAndSigningCertificate = false; - }); - - PreConfigure(builder => - { - builder.AddSigningCertificate(certificate); - builder.AddEncryptionCertificate(certificate); - - builder.UseDataProtection(); - - // 禁用https - builder.UseAspNetCore() - .DisableTransportSecurityRequirement(); - }); - } - else - { - PreConfigure(options => - { - options.AddDeveloperSigningCredential = false; - }); - - PreConfigure(builder => - { - builder.AddSigningCredential(certificate); - }); - } - } - } - else - { - if (configuration.GetValue("AuthServer:UseOpenIddict")) - { - PreConfigure(options => - { - //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html - options.AddDevelopmentEncryptionAndSigningCertificate = false; - }); - - PreConfigure(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(options => - { - // 如果使用持久化存储, 则配置quartz持久层 - if (configuration.GetSection("Quartz:UsePersistentStore").Get()) - { - var settings = configuration.GetSection("Quartz:Properties").Get>(); - 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(elsa => - { - elsa - .AddActivitiesFrom() - .AddWorkflowsFrom() - .AddFeatures(startups, configuration) - .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)); - - elsa.DistributedLockingOptionsBuilder - .UseProviderFactory(sp => name => - { - var provider = sp.GetRequiredService(); - - return provider.CreateLock(name); - }); - }); - - services.AddNotificationHandlersFrom(); - - PreConfigure(mvcBuilder => - { - mvcBuilder.AddApplicationPartIfNotExists(typeof(Elsa.Webhooks.Api.Endpoints.List).Assembly); - }); - } - - private void ConfigureAuthServer(IConfiguration configuration) - { - Configure(builder => - { - builder.DisableTransportSecurityRequirement(); - }); - - Configure(options => - { - options.DisableTransportSecurityRequirement = true; - }); - - Configure(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(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(options => - //{ - // options.EndpointConfigureActions.Add( - // (context) => - // { - // context.Endpoints.MapFallbackToPage("/_Host"); - // }); - //}); - var preActions = services.GetPreConfigureActions(); - - 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(options => - { - options.Limits.MaxRequestBodySize = null; - options.Limits.MaxRequestBufferSize = null; - }); - } - - private void ConfigureBlobStoring(IConfiguration configuration) - { - Configure(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(options => - { - options.NodeName = ApplicationName; - options.JobCleanEnabled = true; - options.JobFetchEnabled = true; - options.JobCheckEnabled = true; - }); - } - - private void ConfigureTextTemplating(IConfiguration configuration) - { - if (configuration.GetValue("TextTemplating:IsDynamicStoreEnabled")) - { - Configure(options => - { - options.IsDynamicTemplateDefinitionStoreEnabled = true; - }); - } - } - - private void ConfigureFeatureManagement(IConfiguration configuration) - { - if (configuration.GetValue("FeatureManagement:IsDynamicStoreEnabled")) - { - Configure(options => - { - options.IsDynamicFeatureStoreEnabled = true; - }); - } - Configure(options => - { - options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = AbpSaasPermissions.Editions.ManageFeatures; - options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = AbpSaasPermissions.Tenants.ManageFeatures; - }); - } - - private void ConfigureSettingManagement(IConfiguration configuration) - { - if (configuration.GetValue("SettingManagement:IsDynamicStoreEnabled")) - { - Configure(options => - { - options.IsDynamicSettingStoreEnabled = true; - }); - } - } - - private void ConfigureWebhooksManagement(IConfiguration configuration) - { - if (configuration.GetValue("WebhooksManagement:IsDynamicStoreEnabled")) - { - Configure(options => - { - options.IsDynamicWebhookStoreEnabled = true; - }); - } - } - /// - /// 配置数据导出 - /// - private void ConfigureExporter() - { - Configure(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 }, - // }; - // }); - }); - } - /// - /// 配置数据权限 - /// - private void ConfigureEntityDataProtected() - { - // Configure(options => - // { - // options.AddEntities(typeof(DemoResource), - // new[] - // { - // typeof(Book), - // }); - // }); - } - - private void ConfigurePermissionManagement(IConfiguration configuration) - { - if (configuration.GetValue("PermissionManagement:IsDynamicStoreEnabled")) - { - Configure(options => - { - options.IsDynamicPermissionStoreEnabled = true; - }); - } - Configure(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("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("NotificationsManagement:IsDynamicStoreEnabled")) - { - Configure(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(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); - } - } - - private void ConfigureVirtualFileSystem() - { - Configure(options => - { - options.FileSets.AddEmbedded("LY.MicroService.Applications.Single"); - }); - } - - private void ConfigureIdempotent() - { - Configure(options => - { - options.IsEnabled = true; - options.DefaultTimeout = 0; - }); - } - - private void ConfigureDbContext() - { - Configure(options => - { - // AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 - // options.UseNpgsql(); - - options.UseMySQL(); - }); - } - - private void ConfigureDataSeeder() - { - Configure(options => - { - options.Resources.Add(new CustomIdentityResources.AvatarUrl()); - }); - } - - private void ConfigureExceptionHandling() - { - // 自定义需要处理的异常 - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - // 自定义需要发送邮件通知的异常类型 - Configure(options => - { - // 是否发送堆栈信息 - options.SendStackTrace = true; - // 未指定异常接收者的默认接收邮件 - // 指定自己的邮件地址 - }); - - Configure(options => - { - options.SendStackTraceToClients = false; - options.SendExceptionsDetailsToClients = false; - }); - } - - private void ConfigureJsonSerializer(IConfiguration configuration) - { - // 统一时间日期格式 - Configure(options => - { - var jsonConfiguration = configuration.GetSection("Json"); - if (jsonConfiguration.Exists()) - { - jsonConfiguration.Bind(options); - } - }); - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - } - - private void ConfigureCaching(IConfiguration configuration) - { - Configure(options => - { - configuration.GetSection("DistributedCache").Bind(options); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - } - - private void ConfigureMultiTenancy(IConfiguration configuration) - { - // 多租户 - Configure(options => - { - options.IsEnabled = true; - }); - - var tenantResolveCfg = configuration.GetSection("App:Domains"); - if (tenantResolveCfg.Exists()) - { - Configure(options => - { - var domains = tenantResolveCfg.Get(); - foreach (var domain in domains) - { - options.AddDomainTenantResolver(domain); - } - }); - } - } - - private void ConfigureAuditing(IConfiguration configuration) - { - Configure(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(); - }); - } - - private void ConfigureIdentity(IConfiguration configuration) - { - // 增加配置文件定义,在新建租户时需要 - Configure(options => - { - var identityConfiguration = configuration.GetSection("Identity"); - if (identityConfiguration.Exists()) - { - identityConfiguration.Bind(options); - } - }); - Configure(options => - { - options.IsDynamicClaimsEnabled = true; - }); - Configure(options => - { - options.IsCleanupEnabled = true; - }); - } - - private void ConfigureMvcUiTheme() - { - Configure(options => - { - //options.StyleBundles.Configure( - // LeptonXLiteThemeBundles.Styles.Global, - // bundle => - // { - // bundle.AddFiles("/global-styles.css"); - // } - //); - }); - } - - private void ConfigureLocalization() - { - Configure(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() - .AddBaseTypes( - typeof(IdentityResource), - typeof(AliyunResource), - typeof(TencentCloudResource), - typeof(WeChatResource), - typeof(PlatformResource), - typeof(AbpOpenIddictResource), - typeof(AbpIdentityServerResource)); - - options.UseAllPersistence(); - }); - - Configure(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(options => - { - options.IsEnabled = true; - // options.IsWrapUnauthorizedEnabled = true; - options.IgnoreNamespaces.Add("Elsa"); - }); - } - - private void PreConfigureWrapper() - { - //PreConfigure(options => - //{ - // options.ProxyRequestActions.Add( - // (appid, httprequestmessage) => - // { - // httprequestmessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); - // }); - //}); - - PreConfigure(options => - { - options.ProxyClientActions.Add( - (_, _, client) => - { - client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); - }); - }); - } - - private void ConfigureAuditing() - { - Configure(options => - { - // options.IsEnabledForGetRequests = true; - options.ApplicationName = ApplicationName; - }); - } - - private void ConfigureUrls(IConfiguration configuration) - { - Configure(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(options => - { - options.AutoValidate = false; - }); - - services.Replace(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(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>(); - }); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs deleted file mode 100644 index ceb61611a..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs +++ /dev/null @@ -1,394 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host; - -[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().SeedAsync(); ; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs deleted file mode 100644 index 42108b0eb..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection -{ - public static class SameSiteCookiesServiceCollectionExtensions - { - public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services) - { - services.Configure(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; - } - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs deleted file mode 100644 index daabe255d..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Volo.Abp.MultiTenancy; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; - -public interface ITenantConfigurationCache -{ - Task RefreshAsync(); - - Task> GetTenantsAsync(); -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs deleted file mode 100644 index 61f939f97..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs +++ /dev/null @@ -1,59 +0,0 @@ -using LINGYUN.Abp.Saas.Tenants; -using Volo.Abp.Caching; -using Volo.Abp.DependencyInjection; -using Volo.Abp.MultiTenancy; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; - -public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency -{ - protected ITenantRepository TenantRepository { get; } - protected IDistributedCache TenantCache { get; } - - public TenantConfigurationCache( - ITenantRepository tenantRepository, - IDistributedCache tenantCache) - { - TenantRepository = tenantRepository; - TenantCache = tenantCache; - } - - public async virtual Task RefreshAsync() - { - var cacheKey = GetCacheKey(); - - await TenantCache.RemoveAsync(cacheKey); - } - - public async virtual Task> GetTenantsAsync() - { - return (await GetForCacheItemAsync()).Tenants; - } - - protected async virtual Task 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"; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs deleted file mode 100644 index ac10549e5..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Volo.Abp.MultiTenancy; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; - -[IgnoreMultiTenancy] -public class TenantConfigurationCacheItem -{ - public List Tenants { get; set; } - - public TenantConfigurationCacheItem() - { - Tenants = new List(); - } - - public TenantConfigurationCacheItem(List tenants) - { - Tenants = tenants; - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj deleted file mode 100644 index 136d24605..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj +++ /dev/null @@ -1,276 +0,0 @@ - - - net8.0 - enable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml deleted file mode 100644 index aed9202eb..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml +++ /dev/null @@ -1,103 +0,0 @@ -@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 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); -} - -

@L["PersonalSettings"]


-
- - - - - - - - - - - - - - - - - - - - @if (CurrentUser.EmailVerified) - { - - } - else - { - @**@ - @L["Validation"].Value - } - - - - - - @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) - { - 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); - } - - - } - else - { - - } - } - } - - - diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js deleted file mode 100644 index 55a88e52e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js +++ /dev/null @@ -1,28 +0,0 @@ -(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); diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml deleted file mode 100644 index d4d8cda0f..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml +++ /dev/null @@ -1,17 +0,0 @@ -@page -@inject IHtmlLocalizer L -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.Abp.Account.Localization -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.EmailConfirmModel -@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout -
-
-

@L["EmailConfirm"]

-
- - - @L["Cancel"] - - -
-
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs deleted file mode 100644 index b2ed2b28e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs +++ /dev/null @@ -1,72 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.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 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 - }); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml deleted file mode 100644 index 8ffc6586b..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml +++ /dev/null @@ -1,13 +0,0 @@ -@page -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.EmailConfirmConfirmationModel -@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.Abp.Account.Localization -@inject IHtmlLocalizer L -
-
-

@L["EmailConfirm"]

-

@L["YourEmailIsSuccessfullyConfirm"]

- @L["GoToTheApplication"] -
-
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs deleted file mode 100644 index 01f1f0f01..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp.Account.Web.Pages.Account; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.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 OnGetAsync() - { - ReturnUrl = await GetRedirectUrlAsync(ReturnUrl, ReturnUrlHash); - - return Page(); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml deleted file mode 100644 index 8d55fdd34..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@page -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.Abp.Account.Localization -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.SendCodeModel -@inject IHtmlLocalizer L - -
-
-

@L["TwoFactor"]

-
- - - -
- -
-
- @L["SendVerifyCode"] -
- - @L["Login"] - - -
-
- diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs deleted file mode 100644 index 8155e20f1..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs +++ /dev/null @@ -1,125 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.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 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 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 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; } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml deleted file mode 100644 index 8f0dd7030..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml +++ /dev/null @@ -1,16 +0,0 @@ -@page -@inject IHtmlLocalizer L -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.Abp.Account.Localization -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.SendEmailConfirmModel -@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout -
-
-

@L["EmailConfirm"]

-
- - @L["Cancel"] - - -
-
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs deleted file mode 100644 index 9d14d5710..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs +++ /dev/null @@ -1,73 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.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 OnGetAsync() - { - Email = CurrentUser.Email; - - return Task.FromResult(Page()); - } - - public async virtual Task 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 - }); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs deleted file mode 100644 index 166f827e9..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs +++ /dev/null @@ -1,63 +0,0 @@ -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 PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account -{ - /// - /// 重写登录模型,实现双因素登录 - /// - [Dependency(ReplaceServices = true)] - [ExposeServices(typeof(LoginModel), typeof(OpenIddictSupportedLoginModel))] - public class TwoFactorSupportedLoginModel : OpenIddictSupportedLoginModel - { - public TwoFactorSupportedLoginModel( - IAuthenticationSchemeProvider schemeProvider, - IOptions accountOptions, - IOptions identityOptions, - IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache, - AbpOpenIddictRequestHelper openIddictRequestHelper) - : base(schemeProvider, accountOptions, identityOptions, identityDynamicClaimsPrincipalContributorCache, openIddictRequestHelper) - { - - } - - protected async override Task> 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 TwoFactorLoginResultAsync() - { - // 重定向双因素认证页面 - return Task.FromResult(RedirectToPage("SendCode", new - { - returnUrl = ReturnUrl, - returnUrlHash = ReturnUrlHash, - rememberMe = LoginInput.RememberMe - })); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml deleted file mode 100644 index 1936197c0..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@page -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.UseRecoveryCodeModel -@{ -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs deleted file mode 100644 index c8ccca339..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account -{ - public class UseRecoveryCodeModel : PageModel - { - public void OnGet() - { - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml deleted file mode 100644 index 2b14e2168..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@page -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.Abp.Account.Localization -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.VerifyAuthenticatorCodeModel -@inject IHtmlLocalizer L -
-
-
- - -
- - - -
-
- - -
- @L["VerifyAuthenticatorCode"] - - @L["Login"] - -
-
-
\ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs deleted file mode 100644 index 899e3df30..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System.ComponentModel.DataAnnotations; -using Volo.Abp.Account.Web.Pages.Account; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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; } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml deleted file mode 100644 index 44d45b36e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml +++ /dev/null @@ -1,29 +0,0 @@ -@page -@inject IHtmlLocalizer L -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.Abp.Account.Localization -@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.VerifyCodeModel -
-
-
- - - - -
- -
- - - - - -
- @L["VerifyAuthenticatorCode"] -
- - @L["ReSendVerifyCode"] - -
-
-
diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs deleted file mode 100644 index 169c48eda..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System.ComponentModel.DataAnnotations; -using Volo.Abp.Account.Localization; -using Volo.Abp.Account.Web.Pages.Account; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account -{ - public class VerifyCodeModel : AccountPageModel - { - [BindProperty] - public VerifyCodeInputModel Input { get; set; } - /// - /// ˫������֤�ṩ���� - /// - [HiddenInput] - [BindProperty(SupportsGet = true)] - public string Provider { get; set; } - /// - /// �ض���Url - /// - [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 VerifyCodeModel() - { - LocalizationResourceType = typeof(AccountResource); - } - - public virtual IActionResult OnGet() - { - Input = new VerifyCodeInputModel(); - - return Page(); - } - - public virtual async Task 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 - { - /// - /// �Ƿ���������м�ס��¼״̬ - /// - public bool RememberBrowser { get; set; } - /// - /// ���͵���֤�� - /// - [Required] - public string VerifyCode { get; set; } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml deleted file mode 100644 index c149bd95d..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml +++ /dev/null @@ -1,36 +0,0 @@ -@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 PackageName.CompanyName.ProjectName.AIO.Host.Pages.IndexModel -@inject ICurrentUser CurrentUser -@if (CurrentUser.IsAuthenticated) -{ -
- - - - Logout - - -

@CurrentUser.UserName

-
@CurrentUser.Email
-
- Roles: @CurrentUser.Roles.JoinAsString(", ") -
- Claims:
- @Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString("
")) -
-
-
-
-} - -@if (!CurrentUser.IsAuthenticated) -{ -
-

- Login -
-} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs deleted file mode 100644 index 7047bc406..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages -{ - public class IndexModel : AbpPageModel - { - public void OnGet() - { - } - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml deleted file mode 100644 index c1da1f5f1..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@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 \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs deleted file mode 100644 index 3daf07fe4..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs +++ /dev/null @@ -1,82 +0,0 @@ -using LINGYUN.Abp.Identity.Session.AspNetCore; -using PackageName.CompanyName.ProjectName.AIO.Host; -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(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(); diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json deleted file mode 100644 index 337677308..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "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" - } - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs deleted file mode 100644 index a4218a9c4..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.Extensions.Options; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; -using Volo.Abp.AspNetCore.MultiTenancy; -using Volo.Abp.MultiTenancy; - -namespace PackageName.CompanyName.ProjectName.AIO.Host; - -public class TenantHeaderParamter : IOperationFilter -{ - private readonly AbpMultiTenancyOptions _multiTenancyOptions; - private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions; - public TenantHeaderParamter( - IOptions multiTenancyOptions, - IOptions aspNetCoreMultiTenancyOptions) - { - _multiTenancyOptions = multiTenancyOptions.Value; - _aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value; - } - - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - if (_multiTenancyOptions.IsEnabled) - { - operation.Parameters = operation.Parameters ?? new List(); - operation.Parameters.Add(new OpenApiParameter - { - Name = _aspNetCoreMultiTenancyOptions.TenantKey, - In = ParameterLocation.Header, - Description = "Tenant Id in http header", - Required = false - }); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs deleted file mode 100644 index 31aafda51..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs +++ /dev/null @@ -1,21 +0,0 @@ -using LINGYUN.Abp.WeChat.Common.Messages.Handlers; -using LINGYUN.Abp.WeChat.Official.Messages.Models; -using LINGYUN.Abp.WeChat.Official.Services; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; -/// -/// 文本消息客服回复 -/// -public class TextMessageReplyContributor : IMessageHandleContributor -{ - public async virtual Task HandleAsync(MessageHandleContext context) - { - var messageSender = context.ServiceProvider.GetRequiredService(); - - 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))); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs deleted file mode 100644 index 806302c0d..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs +++ /dev/null @@ -1,21 +0,0 @@ -using LINGYUN.Abp.WeChat.Common.Messages.Handlers; -using LINGYUN.Abp.WeChat.Official.Messages.Models; -using LINGYUN.Abp.WeChat.Official.Services; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; -/// -/// 用户关注回复消息 -/// -public class UserSubscribeEventContributor : IEventHandleContributor -{ - public async virtual Task HandleAsync(MessageHandleContext context) - { - var messageSender = context.ServiceProvider.GetRequiredService(); - - await messageSender.SendAsync( - new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel( - context.Message.FromUserName, - new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage( - "感谢您的关注, 点击菜单了解更多."))); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs deleted file mode 100644 index f85f858a1..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs +++ /dev/null @@ -1,24 +0,0 @@ -using LINGYUN.Abp.WeChat.Common.Messages.Handlers; -using LINGYUN.Abp.WeChat.Work.Common.Messages.Models; -using LINGYUN.Abp.WeChat.Work.Messages; - -namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Work.Messages; -/// -/// 文本消息客服回复 -/// -public class TextMessageReplyContributor : IMessageHandleContributor -{ - public async virtual Task HandleAsync(MessageHandleContext context) - { - var messageSender = context.ServiceProvider.GetRequiredService(); - - 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, - }); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json deleted file mode 100644 index 4f753c08e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json +++ /dev/null @@ -1,249 +0,0 @@ -{ - "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" - } - } - ] - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json deleted file mode 100644 index ff9beea3e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "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}" - } - } - ] - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js deleted file mode 100644 index bec4d578f..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js +++ /dev/null @@ -1,10 +0,0 @@ -"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(); -}; \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs deleted file mode 100644 index dd8a07ea4..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using PackageName.CompanyName.ProjectName.EntityFrameworkCore; -using Serilog; -using Volo.Abp; -using Volo.Abp.Data; - -namespace PackageName.CompanyName.ProjectName.DbMigrator; - -public class DbMigratorHostedService : IHostedService -{ - private readonly IHostApplicationLifetime _hostApplicationLifetime; - private readonly IConfiguration _configuration; - - public DbMigratorHostedService( - IHostApplicationLifetime hostApplicationLifetime, - IConfiguration configuration) - { - _hostApplicationLifetime = hostApplicationLifetime; - _configuration = configuration; - } - - public async Task StartAsync(CancellationToken cancellationToken) - { - using var application = await AbpApplicationFactory - .CreateAsync(options => - { - options.Configuration.UserSecretsId = Environment.GetEnvironmentVariable("APPLICATION_USER_SECRETS_ID"); - options.Configuration.UserSecretsAssembly = typeof(DbMigratorHostedService).Assembly; - options.Services.ReplaceConfiguration(_configuration); - options.UseAutofac(); - options.Services.AddLogging(c => c.AddSerilog()); - options.AddDataMigrationEnvironment(); - }); - await application.InitializeAsync(); - - await application - .ServiceProvider - .GetRequiredService() - .CheckAndApplyDatabaseMigrationsAsync(); - - await application.ShutdownAsync(); - - _hostApplicationLifetime.StopApplication(); - } - - public Task StopAsync(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } -} - diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj deleted file mode 100644 index b125867ab..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - Exe - net8.0 - enable - enable - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs deleted file mode 100644 index 18b109f71..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs +++ /dev/null @@ -1,13 +0,0 @@ -using PackageName.CompanyName.ProjectName.EntityFrameworkCore; -using Volo.Abp.Autofac; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName.DbMigrator; - -[DependsOn( - typeof(AbpAutofacModule), - typeof(ProjectNameEntityFrameworkCoreModule) - )] -public class PackageNameCompanyNameProjectNameDbMigratorModule : AbpModule -{ -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs deleted file mode 100644 index 087267054..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Serilog; -using Serilog.Events; - -namespace PackageName.CompanyName.ProjectName.DbMigrator; - -public class Program -{ - public async static Task Main(string[] args) - { - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Information() - .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) - .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) -#if DEBUG - .MinimumLevel.Override("PackageName.CompanyName.ProjectName", LogEventLevel.Debug) -#else - .MinimumLevel.Override("PackageName.CompanyName.ProjectName", LogEventLevel.Information) -#endif - .Enrich.FromLogContext() - .WriteTo.File("Logs/logs.txt") - .WriteTo.Console() - .CreateLogger(); - - await CreateHostBuilder(args).RunConsoleAsync(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) - { - return Host.CreateDefaultBuilder(args) - .AddAppSettingsSecretsJson() - .ConfigureLogging((context, logging) => logging.ClearProviders()) - .ConfigureServices((hostContext, services) => - { - services.AddHostedService(); - }); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json deleted file mode 100644 index 17a01bb6a..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json +++ /dev/null @@ -1,147 +0,0 @@ -{ - "AgileConfig": { - "IsEnabled": false, - "env": "DEV", - "appId": "PackageName.CompanyName.ProjectName", - "secret": "1q2w3E*", - "nodes": "http://127.0.0.1:15000", - "name": "PackageName.CompanyName.ProjectName", - "tag": "PackageName.CompanyName.ProjectName" - }, - "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=ProjectName;User Id=root;Password=123456", - "ProjectName": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpSaas": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpFeatureManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpLocalizationManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpTextTemplating": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" - }, - "DistributedLock": { - "IsEnabled": true, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=15" - } - }, - "OpenTelemetry": { - "IsEnabled": true, - "ZipKin": { - "Endpoint": "http://127.0.0.1:9411/api/v2/spans" - } - }, - "RemoteServices": {}, - "IdentityClients": { - "InternalServiceClient": { - "Authority": "http://127.0.0.1:44385", - "RequireHttps": false, - "GrantType": "client_credentials", - "Scope": "lingyun-abp-application", - "ClientId": "InternalServiceClient", - "ClientSecret": "1q2w3E*" - } - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "ProjectName", - "GroupNamePrefix": "Dev", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "MySql": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" - }, - "SqlServer": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" - }, - "Sqlite": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Data Source=./cap.db" - }, - "Oracle": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Data Source=ProjectName;Integrated Security=yes;" - }, - "PostgreSql": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Host=localhost;Port=5432;Database=ProjectName;User ID=root;Password=123456;" - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "123456", - "ExchangeName": "LINGYUN.Abp.Application", - "VirtualHost": "/" - } - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.Abp.Application" - }, - "AuthServer": { - "Authority": "http://127.0.0.1:44385/", - "Audience": "lingyun-abp-application", - "MapInboundClaims": false, - "RequireHttpsMetadata": false, - "SwaggerClientId": "InternalServiceClient", - "SwaggerClientSecret": "1q2w3E*" - }, - "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" - } - } - ] - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json deleted file mode 100644 index d3d63c269..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "StringEncryption": { - "DefaultPassPhrase": "s46c5q55nxpeS8Ra", - "InitVectorBytes": "s83ng0abvd02js84", - "DefaultSalt": "sf&5)s3#" - }, - "AllowedHosts": "*", - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], - "WriteTo": [ - { - "Name": "Console", - "Args": { - "initialMinimumLevel": "Verbose", - "standardErrorFromLevel": "Verbose", - "restrictedToMinimumLevel": "Verbose", - "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", - "fileSizeLimitBytes": 5242880, - "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", - "fileSizeLimitBytes": 5242880, - "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", - "fileSizeLimitBytes": 5242880, - "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", - "fileSizeLimitBytes": 5242880, - "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", - "fileSizeLimitBytes": 5242880, - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" - } - } - ] - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs deleted file mode 100644 index f38f64d84..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc; - -namespace PackageName.CompanyName.ProjectName.Controllers; - -public class HomeController : AbpController -{ - public IActionResult Index() - { - return Redirect("/swagger/index.html"); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile deleted file mode 100644 index b4aa6925f..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0 -LABEL maintainer="colin.in@foxmail.com" -WORKDIR /app - -COPY . /app - -## 设置服务器时区. -## 建议在外部(如docker-compose.yml)中定义 -## Set server time zone. -## Suggest defining it externally (such as Docker Compose. yml) -#ENV TZ=Asia/Shanghai -#RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone - - -## 解决连接SqlServer TLS版本过高问题. -## 如果数据提供者是SqlServer, 且兼容性版本在120及以下,需要手动取消注释. -## The version of connection SqlServer TLS is too high. -## If the data provider is SqlServer and the compatibility version is 120 and below, manual annotation needs to be cancelled. - -#RUN sed -i 's/\[openssl_init\]/# \[openssl_init\]/g' /etc/ssl/openssl.cnf -#RUN sed -i '$a\[openssl_init]' /etc/ssl/openssl.cnf -#RUN sed -i '$a\providers = provider_sect' /etc/ssl/openssl.cnf -#RUN sed -i '$a\ssl_conf = ssl_sect' /etc/ssl/openssl.cnf - # -#RUN sed -i '$a\[provider_sect]' /etc/ssl/openssl.cnf -#RUN sed -i '$a\default = default_sect' /etc/ssl/openssl.cnf -#RUN sed -i '$a\legacy = legacy_sect' /etc/ssl/openssl.cnf - # -#RUN sed -i '$a\[default_sect]' /etc/ssl/openssl.cnf -#RUN sed -i '$a\activate = 1' /etc/ssl/openssl.cnf - # -#RUN sed -i '$a\[legacy_sect]' /etc/ssl/openssl.cnf -#RUN sed -i '$a\activate = 1' /etc/ssl/openssl.cnf - # -#RUN sed -i '$a\[ssl_sect]' /etc/ssl/openssl.cnf -#RUN sed -i '$a\system_default = system_default_sect' /etc/ssl/openssl.cnf - # -#RUN sed -i '$a\[system_default_sect]' /etc/ssl/openssl.cnf -#RUN sed -i '$a\CipherString = DEFAULT:@SECLEVEL=0' /etc/ssl/openssl.cnf - -## 阿里源 -#RUN sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list.d/debian.sources -#RUN apt-get clean -#RUN apt-get update - -## .NET 8.0 默认使用8080端口,变更为80端口需要环境变量ASPNETCORE_HTTP_PORTS=80 -## .NET 8.0 defaults to port 8080, changing to port 80 requires the environment variable ASPNETCORE.HTTP-PORTS=80 -# EXPOSE 8080/tcp -EXPOSE 80/tcp - -VOLUME [ "./app/Logs" ] -VOLUME [ "./app/Modules" ] - -RUN apt update -RUN apt install wget -y - -ENTRYPOINT ["dotnet", "PackageName.CompanyName.ProjectName.HttpApi.Host.dll"] diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj deleted file mode 100644 index 92df8c8a2..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj +++ /dev/null @@ -1,76 +0,0 @@ - - - - net8.0 - PackageName.CompanyName.ProjectName - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs deleted file mode 100644 index 69122a822..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Serilog; -using System; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Volo.Abp.IO; -using Volo.Abp.Modularity.PlugIns; - -namespace PackageName.CompanyName.ProjectName; - -public class Program -{ - public async static Task Main(string[] args) - { - try - { - Console.Title = "Web.Host"; - Log.Information("Starting web host."); - - var builder = WebApplication.CreateBuilder(args); - builder.Host.AddAppSettingsSecretsJson() - .UseAutofac() - .ConfigureAppConfiguration((context, config) => - { - var configuration = config.Build(); - var agileConfigEnabled = configuration["AgileConfig:IsEnabled"]; - if (agileConfigEnabled.IsNullOrEmpty() || bool.Parse(agileConfigEnabled)) - { - config.AddAgileConfig(new AgileConfig.Client.ConfigClient(configuration)); - } - }) - .UseSerilog((context, provider, config) => - { - config.ReadFrom.Configuration(context.Configuration); - }); - await builder.AddApplicationAsync(options => - { - ProjectNameHttpApiHostModule.ApplicationName = Environment.GetEnvironmentVariable("APPLICATION_NAME") - ?? ProjectNameHttpApiHostModule.ApplicationName; - options.ApplicationName = ProjectNameHttpApiHostModule.ApplicationName; - // 搜索 Modules 目录下所有文件作为插件 - // 取消显示引用所有其他项目的模块,改为通过插件的形式引用 - var pluginFolder = Path.Combine( - Directory.GetCurrentDirectory(), "Modules"); - DirectoryHelper.CreateIfNotExists(pluginFolder); - options.PlugInSources.AddFolder( - pluginFolder, - SearchOption.AllDirectories); - }); - var app = builder.Build(); - await app.InitializeApplicationAsync(); - await app.RunAsync(); - return 0; - } - finally - { - Log.CloseAndFlush(); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs deleted file mode 100644 index 74de35a22..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs +++ /dev/null @@ -1,445 +0,0 @@ -using DotNetCore.CAP; -using LINGYUN.Abp.Dapr.Client.ClientProxying; -using LINGYUN.Abp.Dapr.Client.DynamicProxying; -using LINGYUN.Abp.ExceptionHandling; -using LINGYUN.Abp.ExceptionHandling.Emailing; -using LINGYUN.Abp.Localization.CultureMap; -using LINGYUN.Abp.Localization.Persistence; -using LINGYUN.Abp.Serilog.Enrichers.Application; -using LINGYUN.Abp.Serilog.Enrichers.UniqueId; -using LINGYUN.Abp.Wrapper; -using Medallion.Threading; -using Medallion.Threading.Redis; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Caching.StackExchangeRedis; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Microsoft.OpenApi.Models; -using OpenTelemetry.Metrics; -using OpenTelemetry.Resources; -using OpenTelemetry.Trace; -using PackageName.CompanyName.ProjectName.Localization; -using StackExchange.Redis; -using System; -using System.Collections.Generic; -using System.Linq; -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.Auditing; -using Volo.Abp.Caching; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.GlobalFeatures; -using Volo.Abp.Http.Client; -using Volo.Abp.Json; -using Volo.Abp.Json.SystemTextJson; -using Volo.Abp.Localization; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Security.Claims; -using Volo.Abp.Threading; -using Volo.Abp.VirtualFileSystem; -using static IdentityModel.ClaimComparer; - -namespace PackageName.CompanyName.ProjectName; - -public partial class ProjectNameHttpApiHostModule -{ - public static string ApplicationName { get; set; } = "ProjectNameService"; - private const string DefaultCorsPolicyName = "Default"; - private static readonly OneTimeRunner OneTimeRunner = new(); - - private void PreConfigureFeature() - { - OneTimeRunner.Run(() => - { - GlobalFeatureManager.Instance.Modules.Editions().EnableAll(); - }); - } - - private void PreConfigureApp() - { - AbpSerilogEnrichersConsts.ApplicationName = ApplicationName; - - PreConfigure(options => - { - // 以开放端口区别 - options.SnowflakeIdOptions.WorkerId = 5; - options.SnowflakeIdOptions.WorkerIdBits = 5; - options.SnowflakeIdOptions.DatacenterId = 1; - }); - } - - private void PreConfigureCAP(IConfiguration configuration) - { - PreConfigure(options => - { - options -#if MySQL - .UseMySql(sqlOptions => - { - configuration.GetSection("CAP:MySql").Bind(sqlOptions); - }) -#elif SqlServer - .UseSqlServer(sqlOptions => - { - configuration.GetSection("CAP:SqlServer").Bind(sqlOptions); - }) -#elif Sqlite - .UseSqlite(sqlOptions => - { - configuration.GetSection("CAP:Sqlite").Bind(sqlOptions); - }) -#elif Oracle || OracleDevart - .UseOracle(sqlOptions => - { - configuration.GetSection("CAP:Oracle").Bind(sqlOptions); - }) -#elif PostgreSql - .UsePostgreSql(sqlOptions => - { - configuration.GetSection("CAP:PostgreSql").Bind(sqlOptions); - }) -#endif - .UseRabbitMQ(rabbitMQOptions => - { - configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); - }) - .UseDashboard(); - }); - } - - private void ConfigureJsonSerializer(IConfiguration configuration) - { - // 统一时间日期格式 - Configure(options => - { - var jsonConfiguration = configuration.GetSection("Json"); - if (jsonConfiguration.Exists()) - { - jsonConfiguration.Bind(options); - } - }); - // 中文序列化的编码问题 - Configure(options => - { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); - }); - } - - private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration) - { - var distributedLockIsEnabled = configuration["DistributedLock:IsEnabled"]; - if (distributedLockIsEnabled.IsNullOrWhiteSpace() || bool.Parse(distributedLockIsEnabled)) - { - var redis = ConnectionMultiplexer.Connect(configuration["DistributedLock:Redis:Configuration"]); - services.AddSingleton(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); - } - } - - private void ConfigureOpenTelemetry(IServiceCollection services, IConfiguration configuration) - { - var openTelemetryEnabled = configuration["OpenTelemetry:IsEnabled"]; - if (openTelemetryEnabled.IsNullOrEmpty() || bool.Parse(openTelemetryEnabled)) - { - services.AddOpenTelemetry() - .ConfigureResource(resource => - { - resource.AddService(ApplicationName); - }) - .WithTracing(tracing => - { - tracing.AddHttpClientInstrumentation(); - tracing.AddAspNetCoreInstrumentation(); - tracing.AddCapInstrumentation(); - tracing.AddEntityFrameworkCoreInstrumentation(); - tracing.AddSource(ApplicationName); - - var tracingOtlpEndpoint = configuration["OpenTelemetry:Otlp:Endpoint"]; - if (!tracingOtlpEndpoint.IsNullOrWhiteSpace()) - { - tracing.AddOtlpExporter(otlpOptions => - { - otlpOptions.Endpoint = new Uri(tracingOtlpEndpoint); - }); - return; - } - - var zipkinEndpoint = configuration["OpenTelemetry:ZipKin:Endpoint"]; - if (!zipkinEndpoint.IsNullOrWhiteSpace()) - { - tracing.AddZipkinExporter(zipKinOptions => - { - zipKinOptions.Endpoint = new Uri(zipkinEndpoint); - }); - return; - } - }) - .WithMetrics(metrics => - { - metrics.AddRuntimeInstrumentation(); - metrics.AddHttpClientInstrumentation(); - metrics.AddAspNetCoreInstrumentation(); - }); - } - } - - private void ConfigureExceptionHandling() - { - // 自定义需要处理的异常 - Configure(options => - { - // 加入需要处理的异常类型 - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - options.Handlers.Add(); - }); - // 自定义需要发送邮件通知的异常类型 - Configure(options => - { - // 是否发送堆栈信息 - options.SendStackTrace = true; - // 未指定异常接收者的默认接收邮件 - // 指定自己的邮件地址 - }); - } - - private void ConfigureIdentity(IConfiguration configuration) - { - Configure(options => - { - options.IsDynamicClaimsEnabled = true; - var refreshClaimsUrl = configuration["App:RefreshClaimsUrl"]; - if (!refreshClaimsUrl.IsNullOrWhiteSpace()) - { - options.RemoteRefreshUrl = refreshClaimsUrl + options.RemoteRefreshUrl; - } - }); - } - - private void ConfigureAuditing(IConfiguration configuration) - { - Configure(options => - { - options.ApplicationName = ApplicationName; - // 是否启用实体变更记录 - var allEntitiesSelectorIsEnabled = configuration["Auditing:AllEntitiesSelector"]; - if (allEntitiesSelectorIsEnabled.IsNullOrWhiteSpace() || bool.Parse(allEntitiesSelectorIsEnabled)) - { - options.EntityHistorySelectors.AddAllEntities(); - } - }); - } - - private void ConfigureCaching(IConfiguration configuration) - { - Configure(options => - { - configuration.GetSection("DistributedCache").Bind(options); - }); - - Configure(options => - { - var redisConfig = ConfigurationOptions.Parse(options.Configuration); - options.ConfigurationOptions = redisConfig; - options.InstanceName = configuration["Redis:InstanceName"]; - }); - } - - private void ConfigureMvc(IServiceCollection services, IConfiguration configuration) - { - Configure(options => - { - options.ExposeIntegrationServices = true; - }); - - Configure(options => - { - options.EndpointConfigureActions.Add((builder) => - { - builder.Endpoints.MapHealthChecks(configuration["App:HealthChecks"] ?? "/healthz"); - }); - }); - - services.AddHealthChecks(); - } - - private void ConfigureVirtualFileSystem() - { - Configure(options => - { - options.FileSets.AddEmbedded("PackageName.CompanyName.ProjectName"); - }); - } - - private void ConfigureMultiTenancy(IConfiguration configuration) - { - // 多租户 - Configure(options => - { - options.IsEnabled = true; - }); - - var tenantResolveCfg = configuration.GetSection("App:Domains"); - if (tenantResolveCfg.Exists()) - { - Configure(options => - { - var domains = tenantResolveCfg.Get(); - foreach (var domain in domains) - { - options.AddDomainTenantResolver(domain); - } - }); - } - } - - private void ConfigureSwagger(IServiceCollection services) - { - // Swagger - services.AddSwaggerGen( - options => - { - options.SwaggerDoc("v1", new OpenApiInfo { Title = "ProjectName 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(); - }); - } - - private void ConfigureLocalization() - { - // 支持本地化语言类型 - Configure(options => - { - options.Languages.Add(new LanguageInfo("en", "en", "English")); - options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); - }); - - Configure(options => - { - // 持久化本地化资源 - options.SaveStaticLocalizationsToPersistence = true; - options.AddPersistenceResource(); - }); - - Configure(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 ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) - { - Configure(options => - { - // options.AutoValidate = false; - // options.AutoValidateFilter = (type) => !type.Namespace.Contains("elsa", StringComparison.CurrentCultureIgnoreCase); - }); - - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - configuration.GetSection("AuthServer").Bind(options); - }); - - if (!isDevelopment) - { - var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - services - .AddDataProtection() - .SetApplicationName("LINGYUN.Abp.Application") - .PersistKeysToStackExchangeRedis(redis, "LINGYUN.Abp.Application:DataProtection:Protection-Keys"); - } - } - - 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 ConfigureWrapper() - { - Configure(options => - { - // 取消注释包装结果 - options.IsEnabled = true; - }); - } - - private void PreConfigureWrapper() - { - PreConfigure(options => - { - // http服务间调用发送不需要包装结果的请求头 - options.ProxyClientActions.Add( - (_, _, client) => - { - client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); - }); - }); - - PreConfigure(options => - { - // dapr服务间调用发送不需要包装结果的请求头 - options.ProxyRequestActions.Add( - (appId, httpRequestMessage) => - { - httpRequestMessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); - }); - }); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs deleted file mode 100644 index 0419712fb..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs +++ /dev/null @@ -1,127 +0,0 @@ -using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; -using LINGYUN.Abp.AuditLogging.Elasticsearch; -using LINGYUN.Abp.EventBus.CAP; -using LINGYUN.Abp.ExceptionHandling.Emailing; -using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; -using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; -using LINGYUN.Abp.Saas.EntityFrameworkCore; -using LINGYUN.Abp.Serilog.Enrichers.Application; -using LINGYUN.Abp.Serilog.Enrichers.UniqueId; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using PackageName.CompanyName.ProjectName.EntityFrameworkCore; -using PackageName.CompanyName.ProjectName.SettingManagement; -using Volo.Abp; -using Volo.Abp.AspNetCore.Authentication.JwtBearer; -using Volo.Abp.AspNetCore.MultiTenancy; -using Volo.Abp.AspNetCore.Serilog; -using Volo.Abp.Autofac; -using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.DistributedLocking; -using Volo.Abp.FeatureManagement.EntityFrameworkCore; -using Volo.Abp.Http.Client.IdentityModel.Web; -using Volo.Abp.Modularity; -using Volo.Abp.PermissionManagement.EntityFrameworkCore; -using Volo.Abp.SettingManagement.EntityFrameworkCore; -using Volo.Abp.Swashbuckle; -using LINGYUN.Abp.AspNetCore.HttpOverrides; -using LINGYUN.Abp.Identity.Session.AspNetCore; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpSerilogEnrichersApplicationModule), - typeof(AbpSerilogEnrichersUniqueIdModule), - typeof(AbpAuditLoggingElasticsearchModule), - typeof(AbpAspNetCoreSerilogModule), - typeof(ProjectNameApplicationModule), - typeof(ProjectNameHttpApiModule), - typeof(ProjectNameEntityFrameworkCoreModule), - typeof(ProjectNameSettingManagementModule), - typeof(AbpEmailingExceptionHandlingModule), - typeof(AbpCAPEventBusModule), - typeof(AbpHttpClientIdentityModelWebModule), - typeof(AbpAspNetCoreMultiTenancyModule), - typeof(AbpSaasEntityFrameworkCoreModule), - typeof(AbpFeatureManagementEntityFrameworkCoreModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpLocalizationManagementEntityFrameworkCoreModule), - typeof(AbpTextTemplatingEntityFrameworkCoreModule), - typeof(AbpAspNetCoreAuthenticationJwtBearerModule), - typeof(AbpCachingStackExchangeRedisModule), - typeof(AbpDistributedLockingModule), - typeof(AbpAspNetCoreMvcWrapperModule), - typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpIdentitySessionAspNetCoreModule), - typeof(AbpSwashbuckleModule), - typeof(AbpAutofacModule) - )] -public partial class ProjectNameHttpApiHostModule : AbpModule -{ - public override void PreConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - - PreConfigureApp(); - PreConfigureWrapper(); - PreConfigureFeature(); - PreConfigureCAP(configuration); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - var hostingEnvironment = context.Services.GetHostingEnvironment(); - var configuration = context.Services.GetConfiguration(); - - ConfigureWrapper(); - ConfigureLocalization(); - ConfigureExceptionHandling(); - ConfigureVirtualFileSystem(); - ConfigureCaching(configuration); - ConfigureAuditing(configuration); - ConfigureIdentity(configuration); - ConfigureMultiTenancy(configuration); - ConfigureJsonSerializer(configuration); - ConfigureSwagger(context.Services); - ConfigureMvc(context.Services, configuration); - ConfigureCors(context.Services, configuration); - ConfigureOpenTelemetry(context.Services, configuration); - ConfigureDistributedLock(context.Services, configuration); - ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - var app = context.GetApplicationBuilder(); - var env = context.GetEnvironment(); - - app.UseForwardedHeaders(); - app.UseMapRequestLocalization(); - app.UseCorrelationId(); - app.UseStaticFiles(); - app.UseRouting(); - app.UseCors(); - app.UseAuthentication(); - app.UseJwtTokenMiddleware(); - app.UseMultiTenancy(); - app.UseAbpSession(); - app.UseDynamicClaims(); - app.UseAuthorization(); - app.UseSwagger(); - app.UseAbpSwaggerUI(options => - { - options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support ProjectName API"); - - var configuration = context.GetConfiguration(); - options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); - options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); - options.OAuthScopes("ProjectName"); - }); - app.UseAuditing(); - app.UseAbpSerilogEnrichers(); - app.UseConfiguredEndpoints(); - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json deleted file mode 100644 index bfc8f50b6..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:20890", - "sslPort": 0 - } - }, - "profiles": { - "PackageName.CompanyName.ProjectName.HttpApi.Host": { - "commandName": "Project", - "launchBrowser": false, - "dotnetRunMessages": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://127.0.0.1:5000" - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": false, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs deleted file mode 100644 index 265c287de..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.Extensions.Options; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; -using System.Collections.Generic; -using Volo.Abp.MultiTenancy; - -namespace PackageName.CompanyName.ProjectName; - -public class TenantHeaderParamter : IOperationFilter -{ - private readonly AbpMultiTenancyOptions _options; - public TenantHeaderParamter( - IOptions options) - { - _options = options.Value; - } - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - if (_options.IsEnabled) - { - operation.Parameters = operation.Parameters ?? new List(); - operation.Parameters.Add(new OpenApiParameter - { - Name = TenantResolverConsts.DefaultTenantKey, - In = ParameterLocation.Header, - Description = "Tenant Id/Name", - Required = false - }); - } - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json deleted file mode 100644 index f1c0abd6e..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "AgileConfig": { - "IsEnabled": false, - "env": "DEV", - "appId": "PackageName.CompanyName.ProjectName", - "secret": "1q2w3E*", - "nodes": "http://127.0.0.1:15000", - "name": "PackageName.CompanyName.ProjectName", - "tag": "PackageName.CompanyName.ProjectName" - }, - "App": { - "CorsOrigins": "http://127.0.0.1:30000", - "RefreshClaimsUrl": "http://127.0.0.1:30015/", - "HealthChecks": "/healthz" - }, - "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=ProjectName;User Id=root;Password=123456", - "ProjectName": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpSaas": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpFeatureManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpPermissionManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpSettingManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpLocalizationManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", - "AbpTextTemplating": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" - }, - "DistributedLock": { - "IsEnabled": true, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=15" - } - }, - "OpenTelemetry": { - "IsEnabled": true, - "ZipKin": { - "Endpoint": "http://127.0.0.1:9411/api/v2/spans" - } - }, - "RemoteServices": {}, - "IdentityClients": { - "InternalServiceClient": { - "Authority": "http://127.0.0.1:44385", - "RequireHttps": false, - "MapInboundClaims": false, - "GrantType": "client_credentials", - "Scope": "lingyun-abp-application", - "ClientId": "InternalServiceClient", - "ClientSecret": "1q2w3E*" - } - }, - "CAP": { - "EventBus": { - "DefaultGroupName": "ProjectName", - "GroupNamePrefix": "Dev", - "Version": "v1", - "FailedRetryInterval": 300, - "FailedRetryCount": 10 - }, - "MySql": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" - }, - "SqlServer": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" - }, - "Sqlite": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Data Source=./cap.db" - }, - "Oracle": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Data Source=ProjectName;Integrated Security=yes;" - }, - "PostgreSql": { - "TableNamePrefix": "ProjectName_cap", - "ConnectionString": "Host=localhost;Port=5432;Database=ProjectName;User ID=root;Password=123456;" - }, - "RabbitMQ": { - "HostName": "127.0.0.1", - "Port": 5672, - "UserName": "admin", - "Password": "123456", - "ExchangeName": "LINGYUN.Abp.Application", - "VirtualHost": "/" - } - }, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=10", - "InstanceName": "LINGYUN.Abp.Application" - }, - "AuthServer": { - "Authority": "http://127.0.0.1:44385/", - "Audience": "lingyun-abp-application", - "MapInboundClaims": false, - "RequireHttpsMetadata": false, - "SwaggerClientId": "InternalServiceClient", - "SwaggerClientSecret": "1q2w3E*" - }, - "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" - } - } - ] - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json deleted file mode 100644 index 21ae8a60f..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "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": "*", - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft.EntityFrameworkCore": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], - "WriteTo": [ - { - "Name": "Console", - "Args": { - "initialMinimumLevel": "Verbose", - "standardErrorFromLevel": "Verbose", - "restrictedToMinimumLevel": "Verbose", - "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}" - } - } - ] - } -} diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh deleted file mode 100644 index 01a8eb036..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh +++ /dev/null @@ -1 +0,0 @@ -dapr run --app-id ProjectName --app-port 5000 -H 3500 -- dotnet run --no-build \ No newline at end of file diff --git a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh b/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh deleted file mode 100644 index 45013ae98..000000000 --- a/aspnet-core/templates/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh +++ /dev/null @@ -1,2 +0,0 @@ -cd ../src/PackageName.CompanyName.ProjectName.HttpApi.Client -abp generate-proxy -t csharp -m ProjectName -url http://127.0.0.1:5000/ --without-contracts \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj deleted file mode 100644 index 87d603432..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - netstandard2.0;netstandard2.1;net8.0 - PackageName.CompanyName.ProjectName.Application.Contracts - PackageName.CompanyName.ProjectName.Application.Contracts - false - false - false - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs deleted file mode 100644 index 0dd18f176..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs +++ /dev/null @@ -1,18 +0,0 @@ -using PackageName.CompanyName.ProjectName.Localization; -using Volo.Abp.Features; -using Volo.Abp.Localization; - -namespace PackageName.CompanyName.ProjectName.Features; - -public class ProjectNameFeatureDefinitionProvider : FeatureDefinitionProvider -{ - public override void Define(IFeatureDefinitionContext context) - { - var group = context.AddGroup(ProjectNameFeatureNames.GroupName, L("Features:ProjectName")); - } - - private static ILocalizableString L(string name) - { - return LocalizableString.Create(name); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs deleted file mode 100644 index 4af07a047..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.Features; - -public static class ProjectNameFeatureNames -{ - public const string GroupName = "ProjectName"; -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs deleted file mode 100644 index 6cb9ead42..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using LINGYUN.Abp.Dynamic.Queryable; - -namespace PackageName.CompanyName.ProjectName; -/// -/// 提供动态查询接口定义 -/// -/// 实体dto类型 -public interface IProjectNameDynamicQueryableAppService : IDynamicQueryableAppService -{ -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs deleted file mode 100644 index 4a170551b..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs +++ /dev/null @@ -1,22 +0,0 @@ -using PackageName.CompanyName.ProjectName.Localization; -using Volo.Abp.Authorization.Permissions; -using Volo.Abp.Localization; - -namespace PackageName.CompanyName.ProjectName.Permissions; - -public class ProjectNamePermissionDefinitionProvider : PermissionDefinitionProvider -{ - public override void Define(IPermissionDefinitionContext context) - { - var group = context.AddGroup(ProjectNamePermissions.GroupName, L("Permission:ProjectName")); - - group.AddPermission( - ProjectNamePermissions.ManageSettings, - L("Permission:ManageSettings")); - } - - private static LocalizableString L(string name) - { - return LocalizableString.Create(name); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs deleted file mode 100644 index 98a957ff9..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.Permissions; - -public static class ProjectNamePermissions -{ - public const string GroupName = "ProjectName"; - - public const string ManageSettings = GroupName + ".ManageSettings"; -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs deleted file mode 100644 index 9899a0c97..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs +++ /dev/null @@ -1,17 +0,0 @@ -using LINGYUN.Abp.Dynamic.Queryable; -using Volo.Abp.Application; -using Volo.Abp.Authorization; -using Volo.Abp.Features; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpFeaturesModule), - typeof(AbpAuthorizationModule), - typeof(AbpDddApplicationContractsModule), - typeof(AbpDynamicQueryableApplicationContractsModule), - typeof(ProjectNameDomainSharedModule))] -public class ProjectNameApplicationContractsModule : AbpModule -{ -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs deleted file mode 100644 index ef949b273..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace PackageName.CompanyName.ProjectName; - -public static class ProjectNameRemoteServiceConsts -{ - public const string RemoteServiceName = "ProjectName"; - public const string ModuleName = "ProjectName"; -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj deleted file mode 100644 index d376fcd4a..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - net8.0 - PackageName.CompanyName.ProjectName.Application - PackageName.CompanyName.ProjectName.Application - false - false - false - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs deleted file mode 100644 index 458c4dd29..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs +++ /dev/null @@ -1,13 +0,0 @@ -using PackageName.CompanyName.ProjectName.Localization; -using Volo.Abp.Application.Services; - -namespace PackageName.CompanyName.ProjectName; - -public abstract class ProjectNameAppServiceBase : ApplicationService -{ - protected ProjectNameAppServiceBase() - { - LocalizationResource = typeof(ProjectNameResource); - ObjectMapperContext = typeof(ProjectNameApplicationModule); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs deleted file mode 100644 index b16e2bc1b..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs +++ /dev/null @@ -1,10 +0,0 @@ -using AutoMapper; - -namespace PackageName.CompanyName.ProjectName; - -public class ProjectNameApplicationMapperProfile : Profile -{ - public ProjectNameApplicationMapperProfile() - { - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs deleted file mode 100644 index 723aa233e..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs +++ /dev/null @@ -1,27 +0,0 @@ -using LINGYUN.Abp.Dynamic.Queryable; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Application; -using Volo.Abp.Authorization; -using Volo.Abp.AutoMapper; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpAuthorizationModule), - typeof(AbpDddApplicationModule), - typeof(ProjectNameDomainModule), - typeof(ProjectNameApplicationContractsModule), - typeof(AbpDynamicQueryableApplicationModule))] -public class ProjectNameApplicationModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAutoMapperObjectMapper(); - - Configure(options => - { - options.AddProfile(validate: true); - }); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs deleted file mode 100644 index 36e98d204..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs +++ /dev/null @@ -1,19 +0,0 @@ -using LINGYUN.Abp.Dynamic.Queryable; -using PackageName.CompanyName.ProjectName.Localization; - -namespace PackageName.CompanyName.ProjectName; -/// -/// 提供动态查询接口实现 -/// -/// 实体类型 -/// 实体dto类型 -public abstract class ProjectNameDynamicQueryableAppServiceBase : - DynamicQueryableAppService, - IProjectNameDynamicQueryableAppService -{ - protected ProjectNameDynamicQueryableAppServiceBase() - { - LocalizationResource = typeof(ProjectNameResource); - ObjectMapperContext = typeof(ProjectNameApplicationModule); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs deleted file mode 100644 index fd7a017ea..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Volo.Abp.Specifications; - -namespace System.Linq.Expressions; - -internal static class ExpressionFuncExtensions -{ - public static Expression> AndIf( - this Expression> first, - bool condition, - Expression> second) - { - if (condition) - { - return ExpressionFuncExtender.And(first, second); - } - - return first; - } - - public static Expression> OrIf( - this Expression> first, - bool condition, - Expression> second) - { - if (condition) - { - return ExpressionFuncExtender.Or(first, second); - } - - return first; - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj deleted file mode 100644 index 4372fdff4..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - net8.0 - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs deleted file mode 100644 index 81707fa2f..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs +++ /dev/null @@ -1,18 +0,0 @@ -using LINGYUN.Abp.Dapr.Client; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpDaprClientModule), - typeof(ProjectNameApplicationContractsModule))] -public class ProjectNameDaprClientModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddStaticDaprClientProxies( - typeof(ProjectNameApplicationContractsModule).Assembly, - ProjectNameRemoteServiceConsts.RemoteServiceName); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj deleted file mode 100644 index b9172c86a..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - netstandard2.0;netstandard2.1;net8.0 - PackageName.CompanyName.ProjectName.Domain.Shared - PackageName.CompanyName.ProjectName.Domain.Shared - false - false - false - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs deleted file mode 100644 index 11db159c1..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Volo.Abp.Localization; - -namespace PackageName.CompanyName.ProjectName.Localization; - -[LocalizationResourceName("ProjectName")] -public class ProjectNameResource -{ -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json deleted file mode 100644 index a529d6960..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "culture": "en", - "texts": { - "Features:ProjectName": "ProjectName", - "Permission:ProjectName": "ProjectName", - "Permission:ManageSettings": "Manage Settings" - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json deleted file mode 100644 index e2af58de8..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "culture": "zh-Hans", - "texts": { - "Features:ProjectName": "ProjectName", - "Permission:ProjectName": "ProjectName", - "Permission:ManageSettings": "管理设置" - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs deleted file mode 100644 index 6ce706932..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Volo.Abp.ObjectExtending.Modularity; - -namespace PackageName.CompanyName.ProjectName.ObjectExtending; - -public class ProjectNameModuleExtensionConfiguration : ModuleExtensionConfiguration -{ - public ProjectNameModuleExtensionConfiguration ConfigureProjectName( - Action configureAction) - { - return this.ConfigureEntity( - ProjectNameModuleExtensionConsts.EntityNames.Entity, - configureAction - ); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs deleted file mode 100644 index d59e7c515..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Volo.Abp.ObjectExtending.Modularity; - -namespace PackageName.CompanyName.ProjectName.ObjectExtending; - -public static class ProjectNameModuleExtensionConfigurationDictionaryExtensions -{ - public static ModuleExtensionConfigurationDictionary ConfigureProjectName( - this ModuleExtensionConfigurationDictionary modules, - Action configureAction) - { - return modules.ConfigureModule( - ProjectNameModuleExtensionConsts.ModuleName, - configureAction - ); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs deleted file mode 100644 index dd5e13da8..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.ObjectExtending; - -public static class ProjectNameModuleExtensionConsts -{ - public const string ModuleName = "ProjectName"; - - public static class EntityNames - { - public const string Entity = "Entity"; - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs deleted file mode 100644 index 7473c7453..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs +++ /dev/null @@ -1,32 +0,0 @@ -using PackageName.CompanyName.ProjectName.Localization; -using Volo.Abp.Localization; -using Volo.Abp.Localization.ExceptionHandling; -using Volo.Abp.Modularity; -using Volo.Abp.VirtualFileSystem; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpLocalizationModule))] -public class ProjectNameDomainSharedModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.FileSets.AddEmbedded(); - }); - - Configure(options => - { - options.Resources - .Add() - .AddVirtualJson("/PackageName/CompanyName/ProjectName/Localization/Resources"); - }); - - Configure(options => - { - options.MapCodeNamespace(ProjectNameErrorCodes.Namespace, typeof(ProjectNameResource)); - }); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs deleted file mode 100644 index 7a652e651..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PackageName.CompanyName.ProjectName; - -public static class ProjectNameErrorCodes -{ - public const string Namespace = "ProjectName"; -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj deleted file mode 100644 index b8f035091..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - net8.0 - PackageName.CompanyName.ProjectName.Domain - PackageName.CompanyName.ProjectName.Domain - false - false - false - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs deleted file mode 100644 index 290e09398..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs +++ /dev/null @@ -1,54 +0,0 @@ -using LINGYUN.Abp.DataProtection; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Specifications; - -namespace PackageName.CompanyName.ProjectName; -/// -/// 基本仓储接口 -/// -/// 实体类型 -/// 实体主键类型 -public interface IProjectNameBasicRepository : IDataProtectionRepository - where TEntity : class, IEntity -{ - /// - /// 获取过滤后的实体数量 - /// - /// - /// - /// - Task GetCountAsync( - ISpecification specification, - CancellationToken cancellationToken = default); - /// - /// 获取过滤后的实体列表(分页) - /// - /// - /// - /// - /// - /// - /// - Task> GetListAsync( - ISpecification specification, - string sorting = nameof(IEntity.Id), - int maxResultCount = 10, - int skipCount = 0, - CancellationToken cancellationToken = default); - /// - /// 获取过滤后的实体列表 - /// - /// - /// - /// - /// - /// - Task> GetListAsync( - ISpecification specification, - string sorting = nameof(IEntity.Id), - int maxResultCount = 10, - CancellationToken cancellationToken = default); -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs deleted file mode 100644 index 5cd27642b..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace PackageName.CompanyName.ProjectName; - -public static class ProjectNameDbProperties -{ - public static string DbTablePrefix { get; set; } = "ProjectName_"; - - public static string DbSchema { get; set; } = null; - - - public const string ConnectionStringName = "ProjectName"; -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs deleted file mode 100644 index b2cc42748..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs +++ /dev/null @@ -1,11 +0,0 @@ -using AutoMapper; - -namespace PackageName.CompanyName.ProjectName; - -public class ProjectNameDomainMapperProfile : Profile -{ - public ProjectNameDomainMapperProfile() - { - - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs deleted file mode 100644 index 715c1c3b2..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs +++ /dev/null @@ -1,45 +0,0 @@ -using LINGYUN.Abp.DataProtection; -using Microsoft.Extensions.DependencyInjection; -using PackageName.CompanyName.ProjectName.ObjectExtending; -using Volo.Abp.AutoMapper; -using Volo.Abp.Domain.Entities.Events.Distributed; -using Volo.Abp.Modularity; -using Volo.Abp.ObjectExtending.Modularity; -using Volo.Abp.Threading; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpAutoMapperModule), - typeof(AbpDataProtectionModule), - typeof(ProjectNameDomainSharedModule))] -public class ProjectNameDomainModule : AbpModule -{ - private static readonly OneTimeRunner OneTimeRunner = new(); - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAutoMapperObjectMapper(); - - Configure(options => - { - options.AddProfile(validate: true); - }); - - Configure(options => - { - }); - } - - public override void PostConfigureServices(ServiceConfigurationContext context) - { - OneTimeRunner.Run(() => - { - // 扩展实体配置 - //ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( - // ProjectNameModuleExtensionConsts.ModuleName, - // ProjectNameModuleExtensionConsts.EntityNames.Entity, - // typeof(Entity) - //); - }); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs deleted file mode 100644 index 3845b6ba7..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Volo.Abp.Settings; - -namespace PackageName.CompanyName.ProjectName.Settings; - -public class ProjectNameSettingDefinitionProvider : SettingDefinitionProvider -{ - public override void Define(ISettingDefinitionContext context) - { - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs deleted file mode 100644 index 5d6afce6c..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.Settings; - -public static class ProjectNameSettings -{ - public const string GroupName = "ProjectName"; -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs deleted file mode 100644 index 74e3c828a..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Volo.Abp.Specifications; - -namespace System.Linq.Expressions; - -internal static class ExpressionFuncExtensions -{ - public static Expression> AndIf( - this Expression> first, - bool condition, - Expression> second) - { - if (condition) - { - return ExpressionFuncExtender.And(first, second); - } - - return first; - } - - public static Expression> OrIf( - this Expression> first, - bool condition, - Expression> second) - { - if (condition) - { - return ExpressionFuncExtender.Or(first, second); - } - - return first; - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj deleted file mode 100644 index 7c2260bd8..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - net8.0 - PackageName.CompanyName.ProjectName.EntityFrameworkCore - PackageName.CompanyName.ProjectName.EntityFrameworkCore - false - false - false - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs deleted file mode 100644 index 2d68cf660..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs +++ /dev/null @@ -1,77 +0,0 @@ -using LINGYUN.Abp.DataProtection; -using LINGYUN.Abp.DataProtection.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Dynamic.Core; -using System.Threading; -using System.Threading.Tasks; -using Volo.Abp.Domain.Entities; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.Specifications; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; -/// -/// 实现基本接口 -/// -/// 实体类型 -/// 实体主键类型 -public abstract class EfCoreProjectNameRepository : - EfCoreDataProtectionRepository, - IProjectNameBasicRepository - where TEntity : class, IEntity -{ - protected EfCoreProjectNameRepository( - IDbContextProvider dbContextProvider, - IDataAuthorizationService dataAuthorizationService, - IEntityTypeFilterBuilder entityTypeFilterBuilder) - : base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder) - { - } - - public async virtual Task GetCountAsync( - ISpecification specification, - CancellationToken cancellationToken = default) - { - return await (await GetDbSetAsync()) - .Where(specification.ToExpression()) - .CountAsync(GetCancellationToken(cancellationToken)); - } - - public async virtual Task> GetListAsync( - ISpecification specification, - string sorting = nameof(IEntity.Id), - int maxResultCount = 10, - int skipCount = 0, - CancellationToken cancellationToken = default) - { - return await (await GetDbSetAsync()) - .Where(specification.ToExpression()) - .OrderBy(GetSortingOrDefault(sorting)) - .PageBy(skipCount, maxResultCount) - .ToListAsync(GetCancellationToken(cancellationToken)); - } - - public async virtual Task> GetListAsync( - ISpecification specification, - string sorting = nameof(IEntity.Id), - int maxResultCount = 10, - CancellationToken cancellationToken = default) - { - return await (await GetDbSetAsync()) - .Where(specification.ToExpression()) - .OrderBy(GetSortingOrDefault(sorting)) - .Take(maxResultCount) - .ToListAsync(GetCancellationToken(cancellationToken)); - } - - protected virtual string GetSortingOrDefault(string sorting = nameof(IEntity.Id)) - { - if (sorting.IsNullOrWhiteSpace()) - { - return nameof(IEntity.Id); - } - return sorting; - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs deleted file mode 100644 index b9abdef0c..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.Abp.Data; -using Volo.Abp.EntityFrameworkCore; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)] -public interface IProjectNameDbContext : IEfCoreDbContext -{ -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs deleted file mode 100644 index 3b7ad579f..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs +++ /dev/null @@ -1,21 +0,0 @@ -using LINGYUN.Abp.DataProtection.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore; -using Volo.Abp.Data; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)] -public class ProjectNameDbContext : AbpDataProtectionDbContext, IProjectNameDbContext -{ - public ProjectNameDbContext( - DbContextOptions options) : base(options) - { - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - modelBuilder.ConfigureProjectName(); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs deleted file mode 100644 index 04338731b..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Microsoft.Extensions.Configuration; -using System.IO; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; -public class ProjectNameDbContextFactory : IDesignTimeDbContextFactory -{ - public ProjectNameDbContext CreateDbContext(string[] args) - { - var configuration = BuildConfiguration(); - var connectionString = configuration.GetConnectionString("ProjectName"); - - DbContextOptionsBuilder builder = null; - -#if MySQL - builder = new DbContextOptionsBuilder() - .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); -#elif SqlServer - builder = new DbContextOptionsBuilder() - .UseSqlServer(connectionString); -#elif Sqlite - builder = new DbContextOptionsBuilder() - .UseSqlite(connectionString); -#elif Oracle - builder = new DbContextOptionsBuilder() - .UseOracle(connectionString); -#elif OracleDevart - builder = (DbContextOptionsBuilder) new DbContextOptionsBuilder() - .UseOracle(connectionString); -#elif PostgreSql - builder = new DbContextOptionsBuilder() - .UseNpgsql(connectionString); -#endif - - return new ProjectNameDbContext(builder!.Options); - } - - private static IConfigurationRoot BuildConfiguration() - { - var builder = new ConfigurationBuilder() - .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../PackageName.CompanyName.ProjectName.DbMigrator/")) - .AddJsonFile("appsettings.json", optional: false) - .AddJsonFile("appsettings.Development.json", optional: true); - - return builder.Build(); - } -} - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs deleted file mode 100644 index f812977e6..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using Volo.Abp; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -public static class ProjectNameDbContextModelCreatingExtensions -{ - public static void ConfigureProjectName( - this ModelBuilder builder, - Action optionsAction = null) - { - Check.NotNull(builder, nameof(builder)); - - var options = new ProjectNameModelBuilderConfigurationOptions( - ProjectNameDbProperties.DbTablePrefix, - ProjectNameDbProperties.DbSchema - ); - optionsAction?.Invoke(options); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs deleted file mode 100644 index 74a4a39bc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.Extensions.Logging; -using System; -using System.Threading.Tasks; -using Volo.Abp.Data; -using Volo.Abp.DistributedLocking; -using Volo.Abp.EntityFrameworkCore.Migrations; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Uow; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -public class ProjectNameDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase -{ - protected IDataSeeder DataSeeder { get; } - - public ProjectNameDbMigrationEventHandler( - IDataSeeder dataSeeder, - ITenantStore tenantStore, - ICurrentTenant currentTenant, - IUnitOfWorkManager unitOfWorkManager, - IAbpDistributedLock abpDistributedLock, - IDistributedEventBus distributedEventBus, - ILoggerFactory loggerFactory) - : base( - ConnectionStringNameAttribute.GetConnStringName(), - currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) - { - DataSeeder = dataSeeder; - } - - protected async override Task SeedAsync(Guid? tenantId) - { - await DataSeeder.SeedAsync(tenantId); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs deleted file mode 100644 index e64bc081a..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs +++ /dev/null @@ -1,58 +0,0 @@ -using LINGYUN.Abp.Data.DbMigrator; -using LINGYUN.Abp.Saas.Tenants; -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.EventBus.Distributed; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Uow; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -public class ProjectNameDbMigrationService : EfCoreRuntimeDbMigratorBase, ITransientDependency -{ - protected IDataSeeder DataSeeder { get; } - protected IDbSchemaMigrator DbSchemaMigrator { get; } - protected ITenantRepository TenantRepository { get; } - - public ProjectNameDbMigrationService( - IDataSeeder dataSeeder, - IDbSchemaMigrator dbSchemaMigrator, - ITenantRepository tenantRepository, - ICurrentTenant currentTenant, - IUnitOfWorkManager unitOfWorkManager, - IServiceProvider serviceProvider, - IAbpDistributedLock abpDistributedLock, - IDistributedEventBus distributedEventBus, - ILoggerFactory loggerFactory) - : base( - ConnectionStringNameAttribute.GetConnStringName(), - unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) - { - DataSeeder = dataSeeder; - DbSchemaMigrator = dbSchemaMigrator; - TenantRepository = tenantRepository; - } - - protected async override Task LockAndApplyDatabaseMigrationsAsync() - { - await base.LockAndApplyDatabaseMigrationsAsync(); - - var tenants = await TenantRepository.GetListAsync(); - foreach (var tenant in tenants.Where(x => x.IsActive)) - { - await LockAndApplyDatabaseWithTenantMigrationsAsync(tenant.Id); - } - } - - protected async override Task SeedAsync() - { - Logger.LogInformation($"Executing {(!CurrentTenant.IsAvailable ? "host" : CurrentTenant.Name ?? CurrentTenant.GetId().ToString())} database seed..."); - - await DataSeeder.SeedAsync(CurrentTenant.Id); - } -} \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs deleted file mode 100644 index eb9a9214b..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -public static class ProjectNameEfCoreQueryableExtensions -{ - // 在此聚合仓储服务的扩展方法 -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs deleted file mode 100644 index d88c1eb17..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs +++ /dev/null @@ -1,76 +0,0 @@ -using LINGYUN.Abp.Data.DbMigrator; -using LINGYUN.Abp.DataProtection.EntityFrameworkCore; -using LINGYUN.Abp.Saas.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.Modularity; -#if MySQL -using Volo.Abp.EntityFrameworkCore.MySQL; -#elif SqlServer -using Volo.Abp.EntityFrameworkCore.SqlServer; -using Microsoft.EntityFrameworkCore.Infrastructure; -#elif Sqlite -using Volo.Abp.EntityFrameworkCore.Sqlite; -#elif Oracle -using Volo.Abp.EntityFrameworkCore.Oracle; -#elif OracleDevart -using Volo.Abp.EntityFrameworkCore.Oracle.Devart; -#elif PostgreSql -using Volo.Abp.EntityFrameworkCore.PostgreSql; -#endif - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -[DependsOn( - typeof(ProjectNameDomainModule), - typeof(AbpDataDbMigratorModule), - typeof(AbpDataProtectionEntityFrameworkCoreModule), -#if MySQL - typeof(AbpEntityFrameworkCoreMySQLModule), -#elif SqlServer - typeof(AbpEntityFrameworkCoreSqlServerModule), -#elif Sqlite - typeof(AbpEntityFrameworkCoreSqliteModule), -#elif Oracle - typeof(AbpEntityFrameworkCoreOracleModule), -#elif OracleDevart - typeof(AbpEntityFrameworkCoreOracleDevartModule), -#elif PostgreSql - typeof(AbpEntityFrameworkCorePostgreSqlModule), -#endif - typeof(AbpSaasEntityFrameworkCoreModule))] -public class ProjectNameEntityFrameworkCoreModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - // 配置Ef - Configure(options => - { -#if MySQL - options.UseMySQL(); - options.UseMySQL(); -#elif SqlServer - options.UseSqlServer(); - options.UseSqlServer(builder => - { - // see https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-ver16 - // builder.UseCompatibilityLevel(150); - }); -#elif Sqlite - options.UseSqlite(); - options.UseSqlite(); -#elif Oracle || OracleDevart - options.UseOracle(); - options.UseOracle(); -#elif PostgreSql - options.UseNpgsql(); - options.UseNpgsql(); -#endif - }); - - context.Services.AddAbpDbContext(options => - { - options.AddDefaultRepositories(); - }); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs deleted file mode 100644 index ba62d48a8..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using JetBrains.Annotations; -using Volo.Abp.EntityFrameworkCore.Modeling; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -public class ProjectNameModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions -{ - public ProjectNameModelBuilderConfigurationOptions( - [NotNull] string tablePrefix = "", - [CanBeNull] string schema = null) - : base( - tablePrefix, - schema) - { - - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj deleted file mode 100644 index 6d85b6452..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - netstandard2.0;netstandard2.1;net8.0 - PackageName.CompanyName.ProjectName.HttpApi.Client - PackageName.CompanyName.ProjectName.HttpApi.Client - false - false - false - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs deleted file mode 100644 index f6cb1e324..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Http.Client; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpHttpClientModule), - typeof(ProjectNameApplicationContractsModule))] -public class ProjectNameHttpApiClientModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddStaticHttpClientProxies( - typeof(ProjectNameApplicationContractsModule).Assembly, - ProjectNameRemoteServiceConsts.RemoteServiceName); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj deleted file mode 100644 index b8a73da64..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - net8.0 - PackageName.CompanyName.ProjectName.HttpApi - PackageName.CompanyName.ProjectName.HttpApi - false - false - false - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs deleted file mode 100644 index 6797f475c..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs +++ /dev/null @@ -1,12 +0,0 @@ -using PackageName.CompanyName.ProjectName.Localization; -using Volo.Abp.AspNetCore.Mvc; - -namespace PackageName.CompanyName.ProjectName; - -public abstract class ProjectNameControllerBase : AbpControllerBase -{ - protected ProjectNameControllerBase() - { - LocalizationResource = typeof(ProjectNameResource); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs deleted file mode 100644 index 865145f86..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs +++ /dev/null @@ -1,17 +0,0 @@ -using LINGYUN.Abp.Dynamic.Queryable; -using PackageName.CompanyName.ProjectName.Localization; - -namespace PackageName.CompanyName.ProjectName; -/// -/// 提供动态查询控制器实现 -/// -/// 实体dto类型 -public abstract class ProjectNameDynamicQueryableControllerBase : DynamicQueryableControllerBase -{ - protected ProjectNameDynamicQueryableControllerBase( - IDynamicQueryableAppService service) - : base(service) - { - LocalizationResource = typeof(ProjectNameResource); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs deleted file mode 100644 index 90dccd31c..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs +++ /dev/null @@ -1,42 +0,0 @@ -using PackageName.CompanyName.ProjectName.Localization; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc.Localization; -using Volo.Abp.Localization; -using Volo.Abp.Modularity; -using Volo.Abp.Validation.Localization; -using LINGYUN.Abp.Dynamic.Queryable; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpAspNetCoreMvcModule), - typeof(ProjectNameApplicationContractsModule), - typeof(AbpDynamicQueryableHttpApiModule))] -public class ProjectNameHttpApiModule : AbpModule -{ - public override void PreConfigureServices(ServiceConfigurationContext context) - { - PreConfigure(mvcBuilder => - { - mvcBuilder.AddApplicationPartIfNotExists(typeof(ProjectNameHttpApiModule).Assembly); - }); - - PreConfigure(options => - { - options.AddAssemblyResource( - typeof(ProjectNameResource), - typeof(ProjectNameApplicationContractsModule).Assembly); - }); - } - - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.Resources - .Get() - .AddBaseTypes(typeof(AbpValidationResource)); - }); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml deleted file mode 100644 index 1715698cc..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd deleted file mode 100644 index 11da52550..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj deleted file mode 100644 index 66aa001bd..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - net8.0 - PackageName.CompanyName.ProjectName.SettingManagement - PackageName.CompanyName.ProjectName.SettingManagement - false - false - false - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs deleted file mode 100644 index 308135ed0..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs +++ /dev/null @@ -1,7 +0,0 @@ -using LINGYUN.Abp.SettingManagement; - -namespace PackageName.CompanyName.ProjectName.SettingManagement; - -public interface IProjectNameSettingAppService : ISettingAppService, IUserSettingAppService -{ -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs deleted file mode 100644 index 619fdd3ab..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs +++ /dev/null @@ -1,106 +0,0 @@ -using LINGYUN.Abp.SettingManagement; -using Microsoft.AspNetCore.Authorization; -using PackageName.CompanyName.ProjectName.Permissions; -using PackageName.CompanyName.ProjectName.Localization; -using System.Threading.Tasks; -using Volo.Abp.Application.Services; -using Volo.Abp.Features; -using Volo.Abp.MultiTenancy; -using Volo.Abp.SettingManagement; -using Volo.Abp.Settings; -using Volo.Abp.Users; - -namespace PackageName.CompanyName.ProjectName.SettingManagement; - -public class ProjectNameSettingAppService : ApplicationService, IProjectNameSettingAppService -{ - protected ISettingManager SettingManager { get; } - protected ISettingDefinitionManager SettingDefinitionManager { get; } - - public ProjectNameSettingAppService( - ISettingManager settingManager, - ISettingDefinitionManager settingDefinitionManager) - { - SettingManager = settingManager; - SettingDefinitionManager = settingDefinitionManager; - LocalizationResource = typeof(ProjectNameResource); - } - - public virtual async Task GetAllForCurrentTenantAsync() - { - return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString()); - } - - [Authorize] - public virtual async Task GetAllForCurrentUserAsync() - { - return await GetAllForProviderAsync(UserSettingValueProvider.ProviderName, CurrentUser.GetId().ToString()); - } - - public virtual async Task GetAllForGlobalAsync() - { - return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null); - } - - [Authorize(ProjectNamePermissions.ManageSettings)] - public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) - { - // 增加特性检查 - await CheckFeatureAsync(); - - if (CurrentTenant.IsAvailable) - { - foreach (var setting in input.Settings) - { - await SettingManager.SetForTenantAsync(CurrentTenant.GetId(), setting.Name, setting.Value); - } - - await CurrentUnitOfWork.SaveChangesAsync(); - } - } - - [Authorize] - public virtual async Task SetCurrentUserAsync(UpdateSettingsDto input) - { - // 增加特性检查 - await CheckFeatureAsync(); - - foreach (var setting in input.Settings) - { - await SettingManager.SetForCurrentUserAsync(setting.Name, setting.Value); - } - - await CurrentUnitOfWork.SaveChangesAsync(); - } - - [Authorize(ProjectNamePermissions.ManageSettings)] - public virtual async Task SetGlobalAsync(UpdateSettingsDto input) - { - // 增加特性检查 - await CheckFeatureAsync(); - - foreach (var setting in input.Settings) - { - await SettingManager.SetGlobalAsync(setting.Name, setting.Value); - } - - await CurrentUnitOfWork.SaveChangesAsync(); - } - - - protected virtual async Task CheckFeatureAsync() - { - await FeatureChecker.CheckEnabledAsync(SettingManagementFeatures.Enable); - } - - protected virtual async Task GetAllForProviderAsync(string providerName, string providerKey) - { - var settingGroups = new SettingGroupResult(); - - //TODO: 当前项目所有配置项在此定义返回 - - await Task.CompletedTask; - - return settingGroups; - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs deleted file mode 100644 index 58df5fe31..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Asp.Versioning; -using LINGYUN.Abp.SettingManagement; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using PackageName.CompanyName.ProjectName.Permissions; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.AspNetCore.Mvc; - -namespace PackageName.CompanyName.ProjectName.SettingManagement; - -[RemoteService(Name = ProjectNameRemoteServiceConsts.RemoteServiceName)] -[ApiVersion("2.0")] -[Area(ProjectNameRemoteServiceConsts.ModuleName)] -[Route("api/ProjectName/settings")] -public class ProjectNameSettingController : AbpController, IProjectNameSettingAppService -{ - private readonly IProjectNameSettingAppService _settingAppService; - public ProjectNameSettingController(IProjectNameSettingAppService settingAppService) - { - _settingAppService = settingAppService; - } - - [Authorize(ProjectNamePermissions.ManageSettings)] - [HttpPut] - [Route("by-current-tenant")] - public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) - { - await _settingAppService.SetCurrentTenantAsync(input); - } - - [HttpGet] - [Route("by-current-tenant")] - public virtual async Task GetAllForCurrentTenantAsync() - { - return await _settingAppService.GetAllForCurrentTenantAsync(); - } - - [Authorize] - [HttpPut] - [Route("by-current-user")] - public virtual async Task SetCurrentUserAsync(UpdateSettingsDto input) - { - await _settingAppService.SetCurrentTenantAsync(input); - } - - [Authorize] - [HttpGet] - [Route("by-current-user")] - public virtual async Task GetAllForCurrentUserAsync() - { - return await _settingAppService.GetAllForCurrentTenantAsync(); - } - - [Authorize(ProjectNamePermissions.ManageSettings)] - [HttpPut] - [Route("by-global")] - public virtual async Task SetGlobalAsync(UpdateSettingsDto input) - { - await _settingAppService.SetGlobalAsync(input); - } - - [HttpGet] - [Route("by-global")] - public virtual async Task GetAllForGlobalAsync() - { - return await _settingAppService.GetAllForGlobalAsync(); - } -} diff --git a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs b/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs deleted file mode 100644 index 09eb20393..000000000 --- a/aspnet-core/templates/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs +++ /dev/null @@ -1,22 +0,0 @@ -using LINGYUN.Abp.SettingManagement; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.AspNetCore.Mvc; -using Volo.Abp.Modularity; -using Volo.Abp.SettingManagement; - -namespace PackageName.CompanyName.ProjectName.SettingManagement; - -[DependsOn( - typeof(AbpSettingManagementApplicationContractsModule), - typeof(AbpAspNetCoreMvcModule), - typeof(AbpSettingManagementDomainModule))] -public class ProjectNameSettingManagementModule : AbpModule -{ - public override void PreConfigureServices(ServiceConfigurationContext context) - { - PreConfigure(mvcBuilder => - { - mvcBuilder.AddApplicationPartIfNotExists(typeof(ProjectNameSettingManagementModule).Assembly); - }); - } -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj deleted file mode 100644 index 8a875c135..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - - false - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs deleted file mode 100644 index 64198871d..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace PackageName.CompanyName.ProjectName; - -public abstract class ProjectNameApplicationTestBase : ProjectNameTestBase -{ -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs deleted file mode 100644 index 12175d486..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(ProjectNameDomainTestModule), - typeof(ProjectNameApplicationModule) - )] -public class ProjectNameApplicationTestModule : AbpModule -{ -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj deleted file mode 100644 index 09e35ceb3..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - - false - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs deleted file mode 100644 index 01b678fe1..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace PackageName.CompanyName.ProjectName; - -public abstract class ProjectNameDomainTestBase : ProjectNameTestBase -{ -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs deleted file mode 100644 index 55d69b77c..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(ProjectNameTestBaseModule), - typeof(ProjectNameDomainModule) - )] -public class ProjectNameDomainTestModule : AbpModule -{ -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj deleted file mode 100644 index 61d399721..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net8.0 - - false - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs deleted file mode 100644 index 6971ba357..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -public abstract class ProjectNameEntityFrameworkCoreTestBase : ProjectNameTestBase -{ -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs deleted file mode 100644 index 2146db9ca..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using System; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.Modularity; -using Volo.Abp.Uow; - -namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; - -[DependsOn( - typeof(ProjectNameTestBaseModule), - typeof(ProjectNameEntityFrameworkCoreModule) - )] -public class ProjectNameEntityFrameworkCoreTestModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddEntityFrameworkInMemoryDatabase(); - - var databaseName = Guid.NewGuid().ToString(); - - Configure(options => - { - options.Configure(abpDbContextConfigurationContext => - { - abpDbContextConfigurationContext.DbContextOptions.EnableDetailedErrors(); - abpDbContextConfigurationContext.DbContextOptions.EnableSensitiveDataLogging(); - - abpDbContextConfigurationContext.DbContextOptions.UseInMemoryDatabase(databaseName); - }); - }); - - Configure(options => - { - options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions - }); - } -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj deleted file mode 100644 index e983ebfaf..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - net8.0 - - false - - - - - - - - - - - - - - - - - diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs deleted file mode 100644 index 79cca930d..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Threading.Tasks; -using Volo.Abp; -using Volo.Abp.Modularity; -using Volo.Abp.Testing; -using Volo.Abp.Uow; - -namespace PackageName.CompanyName.ProjectName; - -public abstract class ProjectNameTestBase : AbpIntegratedTest - where TStartupModule : IAbpModule -{ - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } - - protected virtual Task WithUnitOfWorkAsync(Func func) - { - return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); - } - - protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) - { - using (var scope = ServiceProvider.CreateScope()) - { - var uowManager = scope.ServiceProvider.GetRequiredService(); - - using (var uow = uowManager.Begin(options)) - { - await action(); - - await uow.CompleteAsync(); - } - } - } - - protected virtual Task WithUnitOfWorkAsync(Func> func) - { - return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); - } - - protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) - { - using (var scope = ServiceProvider.CreateScope()) - { - var uowManager = scope.ServiceProvider.GetRequiredService(); - - using (var uow = uowManager.Begin(options)) - { - var result = await func(); - await uow.CompleteAsync(); - return result; - } - } - } -} diff --git a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs b/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs deleted file mode 100644 index adab3640d..000000000 --- a/aspnet-core/templates/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp; -using Volo.Abp.Authorization; -using Volo.Abp.Autofac; -using Volo.Abp.Features; -using Volo.Abp.MemoryDb; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName; - -[DependsOn( - typeof(AbpAutofacModule), - typeof(AbpTestBaseModule), - typeof(AbpAuthorizationModule), - typeof(AbpFeaturesModule), - typeof(AbpMemoryDbModule) - )] -public class ProjectNameTestBaseModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAlwaysAllowAuthorization(); - } -} From 77bacd2f4c9ba2286078e6a65b33e0a75e95ef6b Mon Sep 17 00:00:00 2001 From: feijie Date: Mon, 30 Dec 2024 00:27:36 +0800 Subject: [PATCH 13/29] =?UTF-8?q?=E2=9C=A8=20feat(=E5=BE=AE=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E6=A8=A1=E6=9D=BF):=20=E6=B7=BB=E5=8A=A0=20Abp=20?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=BE=AE=E6=9C=8D=E5=8A=A1=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=96=87=E4=BB=B6=20PackageName.CompanyName.?= =?UTF-8?q?ProjectName.csproj?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...PackageName.CompanyName.ProjectName.csproj | 30 ++ .../content/.template.config/template.json | 116 +++++ .../.template.config/template.zh-Hans.json | 5 + .../micro/content/Directory.Build.props | 13 + .../micro/content/Directory.Packages.props | 490 ++++++++++++++++++ .../templates/micro/content/NuGet.Config | 12 + aspnet-core/templates/micro/content/README.md | 129 +++++ .../templates/micro/content/README.zh-CN.md | 129 +++++ .../templates/micro/content/common.props | 38 ++ .../micro/content/configureawait.props | 9 + .../DbMigratorHostedService.cs | 53 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ....CompanyName.ProjectName.DbMigrator.csproj | 42 ++ ...eCompanyNameProjectNameDbMigratorModule.cs | 13 + .../Program.cs | 40 ++ .../appsettings.Development.json | 147 ++++++ .../appsettings.json | 80 +++ .../Controllers/HomeController.cs | 12 + .../Dockerfile | 57 ++ ...ompanyName.ProjectName.HttpApi.Host.csproj | 76 +++ .../Program.cs | 65 +++ .../ProjectNameHttpApiHostModule.Configure.cs | 445 ++++++++++++++++ .../ProjectNameHttpApiHostModule.cs | 127 +++++ .../Properties/launchSettings.json | 28 + .../TenantHeaderParamter.cs | 31 ++ .../appsettings.Development.json | 153 ++++++ .../appsettings.json | 88 ++++ .../dapr.sh | 1 + .../generate-proxy.sh | 2 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...e.ProjectName.Application.Contracts.csproj | 27 + .../ProjectNameFeatureDefinitionProvider.cs | 18 + .../Features/ProjectNameFeatureNames.cs | 6 + .../IProjectNameDynamicQueryableAppService.cs | 10 + ...ProjectNamePermissionDefinitionProvider.cs | 22 + .../Permissions/ProjectNamePermissions.cs | 8 + .../ProjectNameApplicationContractsModule.cs | 17 + .../ProjectNameRemoteServiceConsts.cs | 7 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...CompanyName.ProjectName.Application.csproj | 26 + .../ProjectName/ProjectNameAppServiceBase.cs | 13 + .../ProjectNameApplicationMapperProfile.cs | 10 + .../ProjectNameApplicationModule.cs | 27 + ...ojectNameDynamicQueryableAppServiceBase.cs | 19 + .../Expressions/ExpressionFuncExtensions.cs | 32 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...CompanyName.ProjectName.Dapr.Client.csproj | 19 + .../ProjectNameDaprClientModule.cs | 18 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...mpanyName.ProjectName.Domain.Shared.csproj | 30 ++ .../Localization/ProjectNameResource.cs | 8 + .../Localization/Resources/en.json | 8 + .../Localization/Resources/zh-Hans.json | 8 + ...ProjectNameModuleExtensionConfiguration.cs | 16 + ...ensionConfigurationDictionaryExtensions.cs | 19 + .../ProjectNameModuleExtensionConsts.cs | 11 + .../ProjectNameDomainSharedModule.cs | 32 ++ .../ProjectName/ProjectNameErrorCodes.cs | 6 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...Name.CompanyName.ProjectName.Domain.csproj | 27 + .../IProjectNameBasicRepository.cs | 54 ++ .../ProjectName/ProjectNameDbProperties.cs | 11 + .../ProjectNameDomainMapperProfile.cs | 11 + .../ProjectName/ProjectNameDomainModule.cs | 45 ++ .../ProjectNameSettingDefinitionProvider.cs | 10 + .../Settings/ProjectNameSettings.cs | 6 + .../Expressions/ExpressionFuncExtensions.cs | 32 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...ame.ProjectName.EntityFrameworkCore.csproj | 37 ++ .../EfCoreProjectNameRepository.cs | 77 +++ .../IProjectNameDbContext.cs | 9 + .../ProjectNameDbContext.cs | 21 + .../ProjectNameDbContextFactory.cs | 49 ++ ...ectNameDbContextModelCreatingExtensions.cs | 21 + .../ProjectNameDbMigrationEventHandler.cs | 36 ++ .../ProjectNameDbMigrationService.cs | 58 +++ .../ProjectNameEfCoreQueryableExtensions.cs | 6 + .../ProjectNameEntityFrameworkCoreModule.cs | 76 +++ ...ectNameModelBuilderConfigurationOptions.cs | 17 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...panyName.ProjectName.HttpApi.Client.csproj | 24 + .../ProjectNameHttpApiClientModule.cs | 18 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...ame.CompanyName.ProjectName.HttpApi.csproj | 25 + .../ProjectName/ProjectNameControllerBase.cs | 12 + ...ojectNameDynamicQueryableControllerBase.cs | 17 + .../ProjectName/ProjectNameHttpApiModule.cs | 42 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...yName.ProjectName.SettingManagement.csproj | 27 + .../IProjectNameSettingAppService.cs | 7 + .../ProjectNameSettingAppService.cs | 106 ++++ .../ProjectNameSettingController.cs | 69 +++ .../ProjectNameSettingManagementModule.cs | 22 + ...yName.ProjectName.Application.Tests.csproj | 18 + .../ProjectNameApplicationTestBase.cs | 5 + .../ProjectNameApplicationTestModule.cs | 11 + ...ompanyName.ProjectName.Domain.Tests.csproj | 18 + .../ProjectName/ProjectNameDomainTestBase.cs | 5 + .../ProjectNameDomainTestModule.cs | 11 + ...ojectName.EntityFrameworkCore.Tests.csproj | 19 + .../ProjectNameEntityFrameworkCoreTestBase.cs | 5 + ...rojectNameEntityFrameworkCoreTestModule.cs | 38 ++ ...me.CompanyName.ProjectName.TestBase.csproj | 23 + .../ProjectName/ProjectNameTestBase.cs | 58 +++ .../ProjectName/ProjectNameTestBaseModule.cs | 24 + 115 files changed, 4385 insertions(+) create mode 100644 aspnet-core/templates/micro/PackageName.CompanyName.ProjectName.csproj create mode 100644 aspnet-core/templates/micro/content/.template.config/template.json create mode 100644 aspnet-core/templates/micro/content/.template.config/template.zh-Hans.json create mode 100644 aspnet-core/templates/micro/content/Directory.Build.props create mode 100644 aspnet-core/templates/micro/content/Directory.Packages.props create mode 100644 aspnet-core/templates/micro/content/NuGet.Config create mode 100644 aspnet-core/templates/micro/content/README.md create mode 100644 aspnet-core/templates/micro/content/README.zh-CN.md create mode 100644 aspnet-core/templates/micro/content/common.props create mode 100644 aspnet-core/templates/micro/content/configureawait.props create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh create mode 100644 aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs create mode 100644 aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs create mode 100644 aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs diff --git a/aspnet-core/templates/micro/PackageName.CompanyName.ProjectName.csproj b/aspnet-core/templates/micro/PackageName.CompanyName.ProjectName.csproj new file mode 100644 index 000000000..cceabf72e --- /dev/null +++ b/aspnet-core/templates/micro/PackageName.CompanyName.ProjectName.csproj @@ -0,0 +1,30 @@ + + + net8.0 + true + LINGYUN.Abp.MicroService.Templates + 8.3.0 + colin.in@foxmail.com + Abp framework micro-service template + MIT + false + https://github.com/colinin/abp-next-admin + micro webapi cloud + Template + git + https://github.com/colinin/abp-next-admin + true + true + true + true + False + False + + + + + true + content + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/.template.config/template.json b/aspnet-core/templates/micro/content/.template.config/template.json new file mode 100644 index 000000000..d57640554 --- /dev/null +++ b/aspnet-core/templates/micro/content/.template.config/template.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "colin.in@foxmail.com", + "classifications": ["micro", "webapi", "cloud"], + "name": "LINGYUN.Abp.MicroService", + "identity": "LINGYUN.Abp.MicroService", + "description": "Abp framework micro-service template", + "groupIdentity": "LINGYUN.Abp.Application", + "shortName": "lam", + "tags": { + "language": "C#", + "type": "project" + }, + "sources": [ + { + "modifiers": [ + { + "exclude": [ + "**/[Bb]in/**", + "**/[Oo]bj/**", + "**/[Ll]ocalNuget/**", + ".template.config/**/*", + ".vs/**/*", + "**/host/PackageName.CompanyName.ProjectName.AIO.Host/**" + ] + } + ] + } + ], + "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\")" + } + } +} diff --git a/aspnet-core/templates/micro/content/.template.config/template.zh-Hans.json b/aspnet-core/templates/micro/content/.template.config/template.zh-Hans.json new file mode 100644 index 000000000..f0339e4e4 --- /dev/null +++ b/aspnet-core/templates/micro/content/.template.config/template.zh-Hans.json @@ -0,0 +1,5 @@ +{ + "description": "适用于abp框架的微服务模板项目", + "symbols/AuthenticationScheme/description": "认证服务体系, 可选项为: IdentityServer4、OpenIddict, 默认使用IdentityServer4.", + "symbols/DatabaseManagement/description": "数据库管理提供者, 可选项为: SqlServer、MySQL、Sqlite、Oracle、OracleDevart、PostgreSql, 默认使用MySQL." +} diff --git a/aspnet-core/templates/micro/content/Directory.Build.props b/aspnet-core/templates/micro/content/Directory.Build.props new file mode 100644 index 000000000..6f2501679 --- /dev/null +++ b/aspnet-core/templates/micro/content/Directory.Build.props @@ -0,0 +1,13 @@ + + + true + + + + + all + runtime; build; native; contentfiles; analyzers + + + + diff --git a/aspnet-core/templates/micro/content/Directory.Packages.props b/aspnet-core/templates/micro/content/Directory.Packages.props new file mode 100644 index 000000000..433f06afb --- /dev/null +++ b/aspnet-core/templates/micro/content/Directory.Packages.props @@ -0,0 +1,490 @@ + + + 8.2.0 + 2.14.1 + 8.3.0 + 8.3.0 + 8.0.0 + 8.0.0 + 8.0.0 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/NuGet.Config b/aspnet-core/templates/micro/content/NuGet.Config new file mode 100644 index 000000000..ddde6944c --- /dev/null +++ b/aspnet-core/templates/micro/content/NuGet.Config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/README.md b/aspnet-core/templates/micro/content/README.md new file mode 100644 index 000000000..7b7520aef --- /dev/null +++ b/aspnet-core/templates/micro/content/README.md @@ -0,0 +1,129 @@ +# 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 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) +dotnet new lam -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +``` + +#### For All-in-One Project + +```bash +# Short name: laa (LINGYUN Abp AllInOne) +dotnet new laa -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;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 +cd /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 +8.3.0 +``` + +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 diff --git a/aspnet-core/templates/micro/content/README.zh-CN.md b/aspnet-core/templates/micro/content/README.zh-CN.md new file mode 100644 index 000000000..b93d76220 --- /dev/null +++ b/aspnet-core/templates/micro/content/README.zh-CN.md @@ -0,0 +1,129 @@ +# LINGYUN.Abp.Templates + +[English](README.md) | [中文](README.zh-CN.md) + +## 简介 + +LINGYUN.Abp.Templates 基于 ABP Framework 提供两种项目模板: + +1. **微服务模板**:完整的分布式微服务架构模板 +2. **单体应用模板**:将所有服务集成到一个项目中的单体应用模板 + +## 特性 + +### 共同特性 + +- 集成身份认证(支持 IdentityServer4/OpenIddict) +- 数据库集成(支持多种数据库) +- 统一配置管理 +- 分布式事件总线支持 +- 后台作业处理 + +### 微服务模板特性 + +- 完整的微服务项目结构 +- 服务发现与注册 +- 支持分布式部署 + +### 单体应用模板特性 + +- 简化的部署流程 +- 更容易的维护 +- 更低的资源需求 + +## 使用方法 + +### 安装模板 + +```bash +# 安装微服务模板 +dotnet new install LINGYUN.Abp.MicroService.Templates + +# 安装单体应用模板 +dotnet new install LINGYUN.Abp.AllInOne.Templates +``` + +### 创建新项目 + +#### 创建微服务项目 + +```bash +# 简写名称:lam (LINGYUN Abp Microservice) +dotnet new lam -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +``` + +#### 创建单体应用项目 + +```bash +# 简写名称:laa (LINGYUN Abp AllInOne) +labp create MyCompanyName.MyProjectName -pk MyPackageName -t laa -o /Users/feijie/Projects/Tests --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port +``` + +## 运行项目 + +创建项目后,可以使用以下命令运行: + +### 运行微服务项目 + +```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 +cd /aspnet-core/templates/content +``` + +2. 修改版本号 + 编辑项目文件更新版本号: + - 微服务模板:`../PackageName.CompanyName.ProjectName.csproj` + - 单体应用模板:`../PackageName.CompanyName.ProjectName.AIO.csproj` + +```xml +8.3.0 +``` + +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 发布地址和密钥 +- 发布前建议进行完整测试 diff --git a/aspnet-core/templates/micro/content/common.props b/aspnet-core/templates/micro/content/common.props new file mode 100644 index 000000000..d7d7622cf --- /dev/null +++ b/aspnet-core/templates/micro/content/common.props @@ -0,0 +1,38 @@ + + + latest + 8.2.1 + colin + $(NoWarn);CS1591;CS0436;CS8618;NU1803 + https://github.com/colinin/abp-next-admin + $(SolutionDir)LocalNuget + 8.2.1 + MIT + git + https://github.com/colinin/abp-next-admin + true + + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)LocalNuget + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/configureawait.props b/aspnet-core/templates/micro/content/configureawait.props new file mode 100644 index 000000000..3caa88c04 --- /dev/null +++ b/aspnet-core/templates/micro/content/configureawait.props @@ -0,0 +1,9 @@ + + + + + All + runtime; build; native; contentfiles; analyzers + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs new file mode 100644 index 000000000..d279fb30f --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/DbMigratorHostedService.cs @@ -0,0 +1,53 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using Serilog; +using Volo.Abp; +using Volo.Abp.Data; + +namespace PackageName.CompanyName.ProjectName.DbMigrator; + +public class DbMigratorHostedService : IHostedService +{ + private readonly IHostApplicationLifetime _hostApplicationLifetime; + private readonly IConfiguration _configuration; + + public DbMigratorHostedService( + IHostApplicationLifetime hostApplicationLifetime, + IConfiguration configuration) + { + _hostApplicationLifetime = hostApplicationLifetime; + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using var application = await AbpApplicationFactory + .CreateAsync(options => + { + options.Configuration.UserSecretsId = Environment.GetEnvironmentVariable("APPLICATION_USER_SECRETS_ID"); + options.Configuration.UserSecretsAssembly = typeof(DbMigratorHostedService).Assembly; + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + options.Services.AddLogging(c => c.AddSerilog()); + options.AddDataMigrationEnvironment(); + }); + await application.InitializeAsync(); + + await application + .ServiceProvider + .GetRequiredService() + .CheckAndApplyDatabaseMigrationsAsync(); + + await application.ShutdownAsync(); + + _hostApplicationLifetime.StopApplication(); + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} + diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj new file mode 100644 index 000000000..4d69cfc5b --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageName.CompanyName.ProjectName.DbMigrator.csproj @@ -0,0 +1,42 @@ + + + + + + + Exe + net8.0 + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs new file mode 100644 index 000000000..fd08046e4 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/PackageNameCompanyNameProjectNameDbMigratorModule.cs @@ -0,0 +1,13 @@ +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName.DbMigrator; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(ProjectNameEntityFrameworkCoreModule) + )] +public class PackageNameCompanyNameProjectNameDbMigratorModule : AbpModule +{ +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs new file mode 100644 index 000000000..e4739face --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/Program.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; + +namespace PackageName.CompanyName.ProjectName.DbMigrator; + +public class Program +{ + public async static Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) +#if DEBUG + .MinimumLevel.Override("PackageName.CompanyName.ProjectName", LogEventLevel.Debug) +#else + .MinimumLevel.Override("PackageName.CompanyName.ProjectName", LogEventLevel.Information) +#endif + .Enrich.FromLogContext() + .WriteTo.File("Logs/logs.txt") + .WriteTo.Console() + .CreateLogger(); + + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + .ConfigureLogging((context, logging) => logging.ClearProviders()) + .ConfigureServices((hostContext, services) => + { + services.AddHostedService(); + }); + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json new file mode 100644 index 000000000..19ddebe12 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.Development.json @@ -0,0 +1,147 @@ +{ + "AgileConfig": { + "IsEnabled": false, + "env": "DEV", + "appId": "PackageName.CompanyName.ProjectName", + "secret": "1q2w3E*", + "nodes": "http://127.0.0.1:15000", + "name": "PackageName.CompanyName.ProjectName", + "tag": "PackageName.CompanyName.ProjectName" + }, + "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=ProjectName;User Id=root;Password=123456", + "ProjectName": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpSaas": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpFeatureManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpSettingManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpLocalizationManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpTextTemplating": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=15" + } + }, + "OpenTelemetry": { + "IsEnabled": true, + "ZipKin": { + "Endpoint": "http://127.0.0.1:9411/api/v2/spans" + } + }, + "RemoteServices": {}, + "IdentityClients": { + "InternalServiceClient": { + "Authority": "http://127.0.0.1:44385", + "RequireHttps": false, + "GrantType": "client_credentials", + "Scope": "lingyun-abp-application", + "ClientId": "InternalServiceClient", + "ClientSecret": "1q2w3E*" + } + }, + "CAP": { + "EventBus": { + "DefaultGroupName": "ProjectName", + "GroupNamePrefix": "Dev", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" + }, + "SqlServer": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" + }, + "Sqlite": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Data Source=./cap.db" + }, + "Oracle": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Data Source=ProjectName;Integrated Security=yes;" + }, + "PostgreSql": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Host=localhost;Port=5432;Database=ProjectName;User ID=root;Password=123456;" + }, + "RabbitMQ": { + "HostName": "127.0.0.1", + "Port": 5672, + "UserName": "admin", + "Password": "123456", + "ExchangeName": "LINGYUN.Abp.Application", + "VirtualHost": "/" + } + }, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "Authority": "http://127.0.0.1:44385/", + "Audience": "lingyun-abp-application", + "MapInboundClaims": false, + "RequireHttpsMetadata": false, + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "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" + } + } + ] + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json new file mode 100644 index 000000000..2f919b2c2 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.DbMigrator/appsettings.json @@ -0,0 +1,80 @@ +{ + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "AllowedHosts": "*", + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft.EntityFrameworkCore": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "initialMinimumLevel": "Verbose", + "standardErrorFromLevel": "Verbose", + "restrictedToMinimumLevel": "Verbose", + "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", + "fileSizeLimitBytes": 5242880, + "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", + "fileSizeLimitBytes": 5242880, + "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", + "fileSizeLimitBytes": 5242880, + "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", + "fileSizeLimitBytes": 5242880, + "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", + "fileSizeLimitBytes": 5242880, + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs new file mode 100644 index 000000000..5e1bb362a --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Controllers/HomeController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName.Controllers; + +public class HomeController : AbpController +{ + public IActionResult Index() + { + return Redirect("/swagger/index.html"); + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile new file mode 100644 index 000000000..012ce3615 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Dockerfile @@ -0,0 +1,57 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +LABEL maintainer="colin.in@foxmail.com" +WORKDIR /app + +COPY . /app + +## 设置服务器时区. +## 建议在外部(如docker-compose.yml)中定义 +## Set server time zone. +## Suggest defining it externally (such as Docker Compose. yml) +#ENV TZ=Asia/Shanghai +#RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone + + +## 解决连接SqlServer TLS版本过高问题. +## 如果数据提供者是SqlServer, 且兼容性版本在120及以下,需要手动取消注释. +## The version of connection SqlServer TLS is too high. +## If the data provider is SqlServer and the compatibility version is 120 and below, manual annotation needs to be cancelled. + +#RUN sed -i 's/\[openssl_init\]/# \[openssl_init\]/g' /etc/ssl/openssl.cnf +#RUN sed -i '$a\[openssl_init]' /etc/ssl/openssl.cnf +#RUN sed -i '$a\providers = provider_sect' /etc/ssl/openssl.cnf +#RUN sed -i '$a\ssl_conf = ssl_sect' /etc/ssl/openssl.cnf + # +#RUN sed -i '$a\[provider_sect]' /etc/ssl/openssl.cnf +#RUN sed -i '$a\default = default_sect' /etc/ssl/openssl.cnf +#RUN sed -i '$a\legacy = legacy_sect' /etc/ssl/openssl.cnf + # +#RUN sed -i '$a\[default_sect]' /etc/ssl/openssl.cnf +#RUN sed -i '$a\activate = 1' /etc/ssl/openssl.cnf + # +#RUN sed -i '$a\[legacy_sect]' /etc/ssl/openssl.cnf +#RUN sed -i '$a\activate = 1' /etc/ssl/openssl.cnf + # +#RUN sed -i '$a\[ssl_sect]' /etc/ssl/openssl.cnf +#RUN sed -i '$a\system_default = system_default_sect' /etc/ssl/openssl.cnf + # +#RUN sed -i '$a\[system_default_sect]' /etc/ssl/openssl.cnf +#RUN sed -i '$a\CipherString = DEFAULT:@SECLEVEL=0' /etc/ssl/openssl.cnf + +## 阿里源 +#RUN sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list.d/debian.sources +#RUN apt-get clean +#RUN apt-get update + +## .NET 8.0 默认使用8080端口,变更为80端口需要环境变量ASPNETCORE_HTTP_PORTS=80 +## .NET 8.0 defaults to port 8080, changing to port 80 requires the environment variable ASPNETCORE.HTTP-PORTS=80 +# EXPOSE 8080/tcp +EXPOSE 80/tcp + +VOLUME [ "./app/Logs" ] +VOLUME [ "./app/Modules" ] + +RUN apt update +RUN apt install wget -y + +ENTRYPOINT ["dotnet", "PackageName.CompanyName.ProjectName.HttpApi.Host.dll"] diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj new file mode 100644 index 000000000..81a3f0945 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/PackageName.CompanyName.ProjectName.HttpApi.Host.csproj @@ -0,0 +1,76 @@ + + + + net8.0 + PackageName.CompanyName.ProjectName + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs new file mode 100644 index 000000000..092cdeb82 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Program.cs @@ -0,0 +1,65 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.IO; +using Volo.Abp.Modularity.PlugIns; + +namespace PackageName.CompanyName.ProjectName; + +public class Program +{ + public async static Task Main(string[] args) + { + try + { + Console.Title = "Web.Host"; + Log.Information("Starting web host."); + + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .ConfigureAppConfiguration((context, config) => + { + var configuration = config.Build(); + var agileConfigEnabled = configuration["AgileConfig:IsEnabled"]; + if (agileConfigEnabled.IsNullOrEmpty() || bool.Parse(agileConfigEnabled)) + { + config.AddAgileConfig(new AgileConfig.Client.ConfigClient(configuration)); + } + }) + .UseSerilog((context, provider, config) => + { + config.ReadFrom.Configuration(context.Configuration); + }); + await builder.AddApplicationAsync(options => + { + ProjectNameHttpApiHostModule.ApplicationName = Environment.GetEnvironmentVariable("APPLICATION_NAME") + ?? ProjectNameHttpApiHostModule.ApplicationName; + options.ApplicationName = ProjectNameHttpApiHostModule.ApplicationName; + // 搜索 Modules 目录下所有文件作为插件 + // 取消显示引用所有其他项目的模块,改为通过插件的形式引用 + var pluginFolder = Path.Combine( + Directory.GetCurrentDirectory(), "Modules"); + DirectoryHelper.CreateIfNotExists(pluginFolder); + options.PlugInSources.AddFolder( + pluginFolder, + SearchOption.AllDirectories); + }); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + return 0; + } + finally + { + Log.CloseAndFlush(); + } + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs new file mode 100644 index 000000000..e7920d899 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.Configure.cs @@ -0,0 +1,445 @@ +using DotNetCore.CAP; +using LINGYUN.Abp.Dapr.Client.ClientProxying; +using LINGYUN.Abp.Dapr.Client.DynamicProxying; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Localization.Persistence; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.Wrapper; +using Medallion.Threading; +using Medallion.Threading.Redis; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using PackageName.CompanyName.ProjectName.Localization; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +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.Auditing; +using Volo.Abp.Caching; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Http.Client; +using Volo.Abp.Json; +using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Security.Claims; +using Volo.Abp.Threading; +using Volo.Abp.VirtualFileSystem; +using static IdentityModel.ClaimComparer; + +namespace PackageName.CompanyName.ProjectName; + +public partial class ProjectNameHttpApiHostModule +{ + public static string ApplicationName { get; set; } = "ProjectNameService"; + private const string DefaultCorsPolicyName = "Default"; + private static readonly OneTimeRunner OneTimeRunner = new(); + + private void PreConfigureFeature() + { + OneTimeRunner.Run(() => + { + GlobalFeatureManager.Instance.Modules.Editions().EnableAll(); + }); + } + + private void PreConfigureApp() + { + AbpSerilogEnrichersConsts.ApplicationName = ApplicationName; + + PreConfigure(options => + { + // 以开放端口区别 + options.SnowflakeIdOptions.WorkerId = 5; + options.SnowflakeIdOptions.WorkerIdBits = 5; + options.SnowflakeIdOptions.DatacenterId = 1; + }); + } + + private void PreConfigureCAP(IConfiguration configuration) + { + PreConfigure(options => + { + options +#if MySQL + .UseMySql(sqlOptions => + { + configuration.GetSection("CAP:MySql").Bind(sqlOptions); + }) +#elif SqlServer + .UseSqlServer(sqlOptions => + { + configuration.GetSection("CAP:SqlServer").Bind(sqlOptions); + }) +#elif Sqlite + .UseSqlite(sqlOptions => + { + configuration.GetSection("CAP:Sqlite").Bind(sqlOptions); + }) +#elif Oracle || OracleDevart + .UseOracle(sqlOptions => + { + configuration.GetSection("CAP:Oracle").Bind(sqlOptions); + }) +#elif PostgreSql + .UsePostgreSql(sqlOptions => + { + configuration.GetSection("CAP:PostgreSql").Bind(sqlOptions); + }) +#endif + .UseRabbitMQ(rabbitMQOptions => + { + configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions); + }) + .UseDashboard(); + }); + } + + private void ConfigureJsonSerializer(IConfiguration configuration) + { + // 统一时间日期格式 + Configure(options => + { + var jsonConfiguration = configuration.GetSection("Json"); + if (jsonConfiguration.Exists()) + { + jsonConfiguration.Bind(options); + } + }); + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration) + { + var distributedLockIsEnabled = configuration["DistributedLock:IsEnabled"]; + if (distributedLockIsEnabled.IsNullOrWhiteSpace() || bool.Parse(distributedLockIsEnabled)) + { + var redis = ConnectionMultiplexer.Connect(configuration["DistributedLock:Redis:Configuration"]); + services.AddSingleton(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); + } + } + + private void ConfigureOpenTelemetry(IServiceCollection services, IConfiguration configuration) + { + var openTelemetryEnabled = configuration["OpenTelemetry:IsEnabled"]; + if (openTelemetryEnabled.IsNullOrEmpty() || bool.Parse(openTelemetryEnabled)) + { + services.AddOpenTelemetry() + .ConfigureResource(resource => + { + resource.AddService(ApplicationName); + }) + .WithTracing(tracing => + { + tracing.AddHttpClientInstrumentation(); + tracing.AddAspNetCoreInstrumentation(); + tracing.AddCapInstrumentation(); + tracing.AddEntityFrameworkCoreInstrumentation(); + tracing.AddSource(ApplicationName); + + var tracingOtlpEndpoint = configuration["OpenTelemetry:Otlp:Endpoint"]; + if (!tracingOtlpEndpoint.IsNullOrWhiteSpace()) + { + tracing.AddOtlpExporter(otlpOptions => + { + otlpOptions.Endpoint = new Uri(tracingOtlpEndpoint); + }); + return; + } + + var zipkinEndpoint = configuration["OpenTelemetry:ZipKin:Endpoint"]; + if (!zipkinEndpoint.IsNullOrWhiteSpace()) + { + tracing.AddZipkinExporter(zipKinOptions => + { + zipKinOptions.Endpoint = new Uri(zipkinEndpoint); + }); + return; + } + }) + .WithMetrics(metrics => + { + metrics.AddRuntimeInstrumentation(); + metrics.AddHttpClientInstrumentation(); + metrics.AddAspNetCoreInstrumentation(); + }); + } + } + + private void ConfigureExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + // 未指定异常接收者的默认接收邮件 + // 指定自己的邮件地址 + }); + } + + private void ConfigureIdentity(IConfiguration configuration) + { + Configure(options => + { + options.IsDynamicClaimsEnabled = true; + var refreshClaimsUrl = configuration["App:RefreshClaimsUrl"]; + if (!refreshClaimsUrl.IsNullOrWhiteSpace()) + { + options.RemoteRefreshUrl = refreshClaimsUrl + options.RemoteRefreshUrl; + } + }); + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(options => + { + options.ApplicationName = ApplicationName; + // 是否启用实体变更记录 + var allEntitiesSelectorIsEnabled = configuration["Auditing:AllEntitiesSelector"]; + if (allEntitiesSelectorIsEnabled.IsNullOrWhiteSpace() || bool.Parse(allEntitiesSelectorIsEnabled)) + { + options.EntityHistorySelectors.AddAllEntities(); + } + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + configuration.GetSection("DistributedCache").Bind(options); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureMvc(IServiceCollection services, IConfiguration configuration) + { + Configure(options => + { + options.ExposeIntegrationServices = true; + }); + + Configure(options => + { + options.EndpointConfigureActions.Add((builder) => + { + builder.Endpoints.MapHealthChecks(configuration["App:HealthChecks"] ?? "/healthz"); + }); + }); + + services.AddHealthChecks(); + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("PackageName.CompanyName.ProjectName"); + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureSwagger(IServiceCollection services) + { + // Swagger + services.AddSwaggerGen( + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "ProjectName 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(); + }); + } + + private void ConfigureLocalization() + { + // 支持本地化语言类型 + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + }); + + Configure(options => + { + // 持久化本地化资源 + options.SaveStaticLocalizationsToPersistence = true; + options.AddPersistenceResource(); + }); + + Configure(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 ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) + { + Configure(options => + { + // options.AutoValidate = false; + // options.AutoValidateFilter = (type) => !type.Namespace.Contains("elsa", StringComparison.CurrentCultureIgnoreCase); + }); + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + configuration.GetSection("AuthServer").Bind(options); + }); + + if (!isDevelopment) + { + var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + services + .AddDataProtection() + .SetApplicationName("LINGYUN.Abp.Application") + .PersistKeysToStackExchangeRedis(redis, "LINGYUN.Abp.Application:DataProtection:Protection-Keys"); + } + } + + 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 ConfigureWrapper() + { + Configure(options => + { + // 取消注释包装结果 + options.IsEnabled = true; + }); + } + + private void PreConfigureWrapper() + { + PreConfigure(options => + { + // http服务间调用发送不需要包装结果的请求头 + options.ProxyClientActions.Add( + (_, _, client) => + { + client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + }); + }); + + PreConfigure(options => + { + // dapr服务间调用发送不需要包装结果的请求头 + options.ProxyRequestActions.Add( + (appId, httpRequestMessage) => + { + httpRequestMessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + }); + }); + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs new file mode 100644 index 000000000..28d5a1480 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs @@ -0,0 +1,127 @@ +using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.EventBus.CAP; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.SettingManagement; +using Volo.Abp; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.DistributedLocking; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Http.Client.IdentityModel.Web; +using Volo.Abp.Modularity; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.Swashbuckle; +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.Identity.Session.AspNetCore; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpSerilogEnrichersApplicationModule), + typeof(AbpSerilogEnrichersUniqueIdModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(ProjectNameApplicationModule), + typeof(ProjectNameHttpApiModule), + typeof(ProjectNameEntityFrameworkCoreModule), + typeof(ProjectNameSettingManagementModule), + typeof(AbpEmailingExceptionHandlingModule), + typeof(AbpCAPEventBusModule), + typeof(AbpHttpClientIdentityModelWebModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(AbpSaasEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpTextTemplatingEntityFrameworkCoreModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpDistributedLockingModule), + typeof(AbpAspNetCoreMvcWrapperModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpIdentitySessionAspNetCoreModule), + typeof(AbpSwashbuckleModule), + typeof(AbpAutofacModule) + )] +public partial class ProjectNameHttpApiHostModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + PreConfigureApp(); + PreConfigureWrapper(); + PreConfigureFeature(); + PreConfigureCAP(configuration); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + + ConfigureWrapper(); + ConfigureLocalization(); + ConfigureExceptionHandling(); + ConfigureVirtualFileSystem(); + ConfigureCaching(configuration); + ConfigureAuditing(configuration); + ConfigureIdentity(configuration); + ConfigureMultiTenancy(configuration); + ConfigureJsonSerializer(configuration); + ConfigureSwagger(context.Services); + ConfigureMvc(context.Services, configuration); + ConfigureCors(context.Services, configuration); + ConfigureOpenTelemetry(context.Services, configuration); + ConfigureDistributedLock(context.Services, configuration); + ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + app.UseForwardedHeaders(); + app.UseMapRequestLocalization(); + app.UseCorrelationId(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseCors(); + app.UseAuthentication(); + app.UseJwtTokenMiddleware(); + app.UseMultiTenancy(); + app.UseAbpSession(); + app.UseDynamicClaims(); + app.UseAuthorization(); + app.UseSwagger(); + app.UseAbpSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support ProjectName API"); + + var configuration = context.GetConfiguration(); + options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); + options.OAuthScopes("ProjectName"); + }); + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseConfiguredEndpoints(); + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json new file mode 100644 index 000000000..0d9c46f45 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:20890", + "sslPort": 0 + } + }, + "profiles": { + "PackageName.CompanyName.ProjectName.HttpApi.Host": { + "commandName": "Project", + "launchBrowser": false, + "dotnetRunMessages": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://127.0.0.1:5000" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs new file mode 100644 index 000000000..e628695db --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/TenantHeaderParamter.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using System.Collections.Generic; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName; + +public class TenantHeaderParamter : IOperationFilter +{ + private readonly AbpMultiTenancyOptions _options; + public TenantHeaderParamter( + IOptions options) + { + _options = options.Value; + } + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (_options.IsEnabled) + { + operation.Parameters = operation.Parameters ?? new List(); + operation.Parameters.Add(new OpenApiParameter + { + Name = TenantResolverConsts.DefaultTenantKey, + In = ParameterLocation.Header, + Description = "Tenant Id/Name", + Required = false + }); + } + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json new file mode 100644 index 000000000..9f72f9390 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.Development.json @@ -0,0 +1,153 @@ +{ + "AgileConfig": { + "IsEnabled": false, + "env": "DEV", + "appId": "PackageName.CompanyName.ProjectName", + "secret": "1q2w3E*", + "nodes": "http://127.0.0.1:15000", + "name": "PackageName.CompanyName.ProjectName", + "tag": "PackageName.CompanyName.ProjectName" + }, + "App": { + "CorsOrigins": "http://127.0.0.1:30000", + "RefreshClaimsUrl": "http://127.0.0.1:30015/", + "HealthChecks": "/healthz" + }, + "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=ProjectName;User Id=root;Password=123456", + "ProjectName": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpSaas": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpFeatureManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpPermissionManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpSettingManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpLocalizationManagement": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "AbpTextTemplating": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=15" + } + }, + "OpenTelemetry": { + "IsEnabled": true, + "ZipKin": { + "Endpoint": "http://127.0.0.1:9411/api/v2/spans" + } + }, + "RemoteServices": {}, + "IdentityClients": { + "InternalServiceClient": { + "Authority": "http://127.0.0.1:44385", + "RequireHttps": false, + "MapInboundClaims": false, + "GrantType": "client_credentials", + "Scope": "lingyun-abp-application", + "ClientId": "InternalServiceClient", + "ClientSecret": "1q2w3E*" + } + }, + "CAP": { + "EventBus": { + "DefaultGroupName": "ProjectName", + "GroupNamePrefix": "Dev", + "Version": "v1", + "FailedRetryInterval": 300, + "FailedRetryCount": 10 + }, + "MySql": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" + }, + "SqlServer": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" + }, + "Sqlite": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Data Source=./cap.db" + }, + "Oracle": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Data Source=ProjectName;Integrated Security=yes;" + }, + "PostgreSql": { + "TableNamePrefix": "ProjectName_cap", + "ConnectionString": "Host=localhost;Port=5432;Database=ProjectName;User ID=root;Password=123456;" + }, + "RabbitMQ": { + "HostName": "127.0.0.1", + "Port": 5672, + "UserName": "admin", + "Password": "123456", + "ExchangeName": "LINGYUN.Abp.Application", + "VirtualHost": "/" + } + }, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=10", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "Authority": "http://127.0.0.1:44385/", + "Audience": "lingyun-abp-application", + "MapInboundClaims": false, + "RequireHttpsMetadata": false, + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "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" + } + } + ] + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json new file mode 100644 index 000000000..b9c69ab64 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/appsettings.json @@ -0,0 +1,88 @@ +{ + "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": "*", + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft.EntityFrameworkCore": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "initialMinimumLevel": "Verbose", + "standardErrorFromLevel": "Verbose", + "restrictedToMinimumLevel": "Verbose", + "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}" + } + } + ] + } +} diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh new file mode 100644 index 000000000..01a8eb036 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/dapr.sh @@ -0,0 +1 @@ +dapr run --app-id ProjectName --app-port 5000 -H 3500 -- dotnet run --no-build \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh new file mode 100644 index 000000000..45013ae98 --- /dev/null +++ b/aspnet-core/templates/micro/content/host/PackageName.CompanyName.ProjectName.HttpApi.Host/generate-proxy.sh @@ -0,0 +1,2 @@ +cd ../src/PackageName.CompanyName.ProjectName.HttpApi.Client +abp generate-proxy -t csharp -m ProjectName -url http://127.0.0.1:5000/ --without-contracts \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj new file mode 100644 index 000000000..0eaa24015 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj @@ -0,0 +1,27 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + PackageName.CompanyName.ProjectName.Application.Contracts + PackageName.CompanyName.ProjectName.Application.Contracts + false + false + false + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs new file mode 100644 index 000000000..5fed2b916 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs @@ -0,0 +1,18 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; + +namespace PackageName.CompanyName.ProjectName.Features; + +public class ProjectNameFeatureDefinitionProvider : FeatureDefinitionProvider +{ + public override void Define(IFeatureDefinitionContext context) + { + var group = context.AddGroup(ProjectNameFeatureNames.GroupName, L("Features:ProjectName")); + } + + private static ILocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs new file mode 100644 index 000000000..6389fbcf6 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName.Features; + +public static class ProjectNameFeatureNames +{ + public const string GroupName = "ProjectName"; +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs new file mode 100644 index 000000000..6f132d9a3 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs @@ -0,0 +1,10 @@ +using LINGYUN.Abp.Dynamic.Queryable; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 提供动态查询接口定义 +/// +/// 实体dto类型 +public interface IProjectNameDynamicQueryableAppService : IDynamicQueryableAppService +{ +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs new file mode 100644 index 000000000..4a170551b --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs @@ -0,0 +1,22 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace PackageName.CompanyName.ProjectName.Permissions; + +public class ProjectNamePermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var group = context.AddGroup(ProjectNamePermissions.GroupName, L("Permission:ProjectName")); + + group.AddPermission( + ProjectNamePermissions.ManageSettings, + L("Permission:ManageSettings")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs new file mode 100644 index 000000000..98a957ff9 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs @@ -0,0 +1,8 @@ +namespace PackageName.CompanyName.ProjectName.Permissions; + +public static class ProjectNamePermissions +{ + public const string GroupName = "ProjectName"; + + public const string ManageSettings = GroupName + ".ManageSettings"; +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs new file mode 100644 index 000000000..eb0b2fb15 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs @@ -0,0 +1,17 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.Features; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpFeaturesModule), + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationContractsModule), + typeof(AbpDynamicQueryableApplicationContractsModule), + typeof(ProjectNameDomainSharedModule))] +public class ProjectNameApplicationContractsModule : AbpModule +{ +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs new file mode 100644 index 000000000..4b5bb260d --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace PackageName.CompanyName.ProjectName; + +public static class ProjectNameRemoteServiceConsts +{ + public const string RemoteServiceName = "ProjectName"; + public const string ModuleName = "ProjectName"; +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj new file mode 100644 index 000000000..cf195e665 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj @@ -0,0 +1,26 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.Application + PackageName.CompanyName.ProjectName.Application + false + false + false + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs new file mode 100644 index 000000000..496140dfe --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs @@ -0,0 +1,13 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Application.Services; + +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameAppServiceBase : ApplicationService +{ + protected ProjectNameAppServiceBase() + { + LocalizationResource = typeof(ProjectNameResource); + ObjectMapperContext = typeof(ProjectNameApplicationModule); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs new file mode 100644 index 000000000..0ace9b456 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs @@ -0,0 +1,10 @@ +using AutoMapper; + +namespace PackageName.CompanyName.ProjectName; + +public class ProjectNameApplicationMapperProfile : Profile +{ + public ProjectNameApplicationMapperProfile() + { + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs new file mode 100644 index 000000000..6e1cf009f --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs @@ -0,0 +1,27 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationModule), + typeof(ProjectNameDomainModule), + typeof(ProjectNameApplicationContractsModule), + typeof(AbpDynamicQueryableApplicationModule))] +public class ProjectNameApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs new file mode 100644 index 000000000..e20348b53 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs @@ -0,0 +1,19 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using PackageName.CompanyName.ProjectName.Localization; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 提供动态查询接口实现 +/// +/// 实体类型 +/// 实体dto类型 +public abstract class ProjectNameDynamicQueryableAppServiceBase : + DynamicQueryableAppService, + IProjectNameDynamicQueryableAppService +{ + protected ProjectNameDynamicQueryableAppServiceBase() + { + LocalizationResource = typeof(ProjectNameResource); + ObjectMapperContext = typeof(ProjectNameApplicationModule); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs new file mode 100644 index 000000000..fd7a017ea --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs @@ -0,0 +1,32 @@ +using Volo.Abp.Specifications; + +namespace System.Linq.Expressions; + +internal static class ExpressionFuncExtensions +{ + public static Expression> AndIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.And(first, second); + } + + return first; + } + + public static Expression> OrIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.Or(first, second); + } + + return first; + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj new file mode 100644 index 000000000..aa6f4772b --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj @@ -0,0 +1,19 @@ + + + + + + + net8.0 + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs new file mode 100644 index 000000000..ca16b0bf1 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs @@ -0,0 +1,18 @@ +using LINGYUN.Abp.Dapr.Client; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpDaprClientModule), + typeof(ProjectNameApplicationContractsModule))] +public class ProjectNameDaprClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddStaticDaprClientProxies( + typeof(ProjectNameApplicationContractsModule).Assembly, + ProjectNameRemoteServiceConsts.RemoteServiceName); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj new file mode 100644 index 000000000..cd98bbcf9 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj @@ -0,0 +1,30 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + PackageName.CompanyName.ProjectName.Domain.Shared + PackageName.CompanyName.ProjectName.Domain.Shared + false + false + false + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs new file mode 100644 index 000000000..b0c280d5a --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace PackageName.CompanyName.ProjectName.Localization; + +[LocalizationResourceName("ProjectName")] +public class ProjectNameResource +{ +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json new file mode 100644 index 000000000..d14e6f1dd --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json @@ -0,0 +1,8 @@ +{ + "culture": "en", + "texts": { + "Features:ProjectName": "ProjectName", + "Permission:ProjectName": "ProjectName", + "Permission:ManageSettings": "Manage Settings" + } +} \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..c85b3754a --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json @@ -0,0 +1,8 @@ +{ + "culture": "zh-Hans", + "texts": { + "Features:ProjectName": "ProjectName", + "Permission:ProjectName": "ProjectName", + "Permission:ManageSettings": "管理设置" + } +} \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs new file mode 100644 index 000000000..6634ceb15 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs @@ -0,0 +1,16 @@ +using System; +using Volo.Abp.ObjectExtending.Modularity; + +namespace PackageName.CompanyName.ProjectName.ObjectExtending; + +public class ProjectNameModuleExtensionConfiguration : ModuleExtensionConfiguration +{ + public ProjectNameModuleExtensionConfiguration ConfigureProjectName( + Action configureAction) + { + return this.ConfigureEntity( + ProjectNameModuleExtensionConsts.EntityNames.Entity, + configureAction + ); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs new file mode 100644 index 000000000..fabfd40c9 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.ObjectExtending.Modularity; + +namespace PackageName.CompanyName.ProjectName.ObjectExtending; + +public static class ProjectNameModuleExtensionConfigurationDictionaryExtensions +{ + public static ModuleExtensionConfigurationDictionary ConfigureProjectName( + this ModuleExtensionConfigurationDictionary modules, + Action configureAction) + { + return modules.ConfigureModule( + ProjectNameModuleExtensionConsts.ModuleName, + configureAction + ); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs new file mode 100644 index 000000000..1973ef9b6 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs @@ -0,0 +1,11 @@ +namespace PackageName.CompanyName.ProjectName.ObjectExtending; + +public static class ProjectNameModuleExtensionConsts +{ + public const string ModuleName = "ProjectName"; + + public static class EntityNames + { + public const string Entity = "Entity"; + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs new file mode 100644 index 000000000..ec682b498 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs @@ -0,0 +1,32 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpLocalizationModule))] +public class ProjectNameDomainSharedModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add() + .AddVirtualJson("/PackageName/CompanyName/ProjectName/Localization/Resources"); + }); + + Configure(options => + { + options.MapCodeNamespace(ProjectNameErrorCodes.Namespace, typeof(ProjectNameResource)); + }); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs new file mode 100644 index 000000000..b2383ee40 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName; + +public static class ProjectNameErrorCodes +{ + public const string Namespace = "ProjectName"; +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj new file mode 100644 index 000000000..2cccd0944 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj @@ -0,0 +1,27 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.Domain + PackageName.CompanyName.ProjectName.Domain + false + false + false + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs new file mode 100644 index 000000000..290e09398 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs @@ -0,0 +1,54 @@ +using LINGYUN.Abp.DataProtection; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Specifications; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 基本仓储接口 +/// +/// 实体类型 +/// 实体主键类型 +public interface IProjectNameBasicRepository : IDataProtectionRepository + where TEntity : class, IEntity +{ + /// + /// 获取过滤后的实体数量 + /// + /// + /// + /// + Task GetCountAsync( + ISpecification specification, + CancellationToken cancellationToken = default); + /// + /// 获取过滤后的实体列表(分页) + /// + /// + /// + /// + /// + /// + /// + Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + int skipCount = 0, + CancellationToken cancellationToken = default); + /// + /// 获取过滤后的实体列表 + /// + /// + /// + /// + /// + /// + Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs new file mode 100644 index 000000000..a18947c6c --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs @@ -0,0 +1,11 @@ +namespace PackageName.CompanyName.ProjectName; + +public static class ProjectNameDbProperties +{ + public static string DbTablePrefix { get; set; } = "ProjectName_"; + + public static string DbSchema { get; set; } = null; + + + public const string ConnectionStringName = "ProjectName"; +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs new file mode 100644 index 000000000..79c7af553 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs @@ -0,0 +1,11 @@ +using AutoMapper; + +namespace PackageName.CompanyName.ProjectName; + +public class ProjectNameDomainMapperProfile : Profile +{ + public ProjectNameDomainMapperProfile() + { + + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs new file mode 100644 index 000000000..401aa849e --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.DataProtection; +using Microsoft.Extensions.DependencyInjection; +using PackageName.CompanyName.ProjectName.ObjectExtending; +using Volo.Abp.AutoMapper; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.Modularity; +using Volo.Abp.ObjectExtending.Modularity; +using Volo.Abp.Threading; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpDataProtectionModule), + typeof(ProjectNameDomainSharedModule))] +public class ProjectNameDomainModule : AbpModule +{ + private static readonly OneTimeRunner OneTimeRunner = new(); + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + }); + } + + public override void PostConfigureServices(ServiceConfigurationContext context) + { + OneTimeRunner.Run(() => + { + // 扩展实体配置 + //ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( + // ProjectNameModuleExtensionConsts.ModuleName, + // ProjectNameModuleExtensionConsts.EntityNames.Entity, + // typeof(Entity) + //); + }); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs new file mode 100644 index 000000000..cdfdef118 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Settings; + +namespace PackageName.CompanyName.ProjectName.Settings; + +public class ProjectNameSettingDefinitionProvider : SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs new file mode 100644 index 000000000..deb0b7b71 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName.Settings; + +public static class ProjectNameSettings +{ + public const string GroupName = "ProjectName"; +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs new file mode 100644 index 000000000..fd7a017ea --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs @@ -0,0 +1,32 @@ +using Volo.Abp.Specifications; + +namespace System.Linq.Expressions; + +internal static class ExpressionFuncExtensions +{ + public static Expression> AndIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.And(first, second); + } + + return first; + } + + public static Expression> OrIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.Or(first, second); + } + + return first; + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj new file mode 100644 index 000000000..05ba83db3 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj @@ -0,0 +1,37 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.EntityFrameworkCore + PackageName.CompanyName.ProjectName.EntityFrameworkCore + false + false + false + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs new file mode 100644 index 000000000..2d68cf660 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs @@ -0,0 +1,77 @@ +using LINGYUN.Abp.DataProtection; +using LINGYUN.Abp.DataProtection.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Specifications; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; +/// +/// 实现基本接口 +/// +/// 实体类型 +/// 实体主键类型 +public abstract class EfCoreProjectNameRepository : + EfCoreDataProtectionRepository, + IProjectNameBasicRepository + where TEntity : class, IEntity +{ + protected EfCoreProjectNameRepository( + IDbContextProvider dbContextProvider, + IDataAuthorizationService dataAuthorizationService, + IEntityTypeFilterBuilder entityTypeFilterBuilder) + : base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder) + { + } + + public async virtual Task GetCountAsync( + ISpecification specification, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(specification.ToExpression()) + .CountAsync(GetCancellationToken(cancellationToken)); + } + + public async virtual Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + int skipCount = 0, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(specification.ToExpression()) + .OrderBy(GetSortingOrDefault(sorting)) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public async virtual Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(specification.ToExpression()) + .OrderBy(GetSortingOrDefault(sorting)) + .Take(maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + protected virtual string GetSortingOrDefault(string sorting = nameof(IEntity.Id)) + { + if (sorting.IsNullOrWhiteSpace()) + { + return nameof(IEntity.Id); + } + return sorting; + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs new file mode 100644 index 000000000..c39c2923e --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)] +public interface IProjectNameDbContext : IEfCoreDbContext +{ +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs new file mode 100644 index 000000000..5cb2c015b --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.DataProtection.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)] +public class ProjectNameDbContext : AbpDataProtectionDbContext, IProjectNameDbContext +{ + public ProjectNameDbContext( + DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureProjectName(); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs new file mode 100644 index 000000000..d9ffcb9ca --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using System.IO; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; +public class ProjectNameDbContextFactory : IDesignTimeDbContextFactory +{ + public ProjectNameDbContext CreateDbContext(string[] args) + { + var configuration = BuildConfiguration(); + var connectionString = configuration.GetConnectionString("ProjectName"); + + DbContextOptionsBuilder builder = null; + +#if MySQL + builder = new DbContextOptionsBuilder() + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); +#elif SqlServer + builder = new DbContextOptionsBuilder() + .UseSqlServer(connectionString); +#elif Sqlite + builder = new DbContextOptionsBuilder() + .UseSqlite(connectionString); +#elif Oracle + builder = new DbContextOptionsBuilder() + .UseOracle(connectionString); +#elif OracleDevart + builder = (DbContextOptionsBuilder) new DbContextOptionsBuilder() + .UseOracle(connectionString); +#elif PostgreSql + builder = new DbContextOptionsBuilder() + .UseNpgsql(connectionString); +#endif + + return new ProjectNameDbContext(builder!.Options); + } + + private static IConfigurationRoot BuildConfiguration() + { + var builder = new ConfigurationBuilder() + .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../PackageName.CompanyName.ProjectName.DbMigrator/")) + .AddJsonFile("appsettings.json", optional: false) + .AddJsonFile("appsettings.Development.json", optional: true); + + return builder.Build(); + } +} + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..726b4ec9a --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using System; +using Volo.Abp; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public static class ProjectNameDbContextModelCreatingExtensions +{ + public static void ConfigureProjectName( + this ModelBuilder builder, + Action optionsAction = null) + { + Check.NotNull(builder, nameof(builder)); + + var options = new ProjectNameModelBuilderConfigurationOptions( + ProjectNameDbProperties.DbTablePrefix, + ProjectNameDbProperties.DbSchema + ); + optionsAction?.Invoke(options); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs new file mode 100644 index 000000000..74a4a39bc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DistributedLocking; +using Volo.Abp.EntityFrameworkCore.Migrations; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public class ProjectNameDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase +{ + protected IDataSeeder DataSeeder { get; } + + public ProjectNameDbMigrationEventHandler( + IDataSeeder dataSeeder, + ITenantStore tenantStore, + ICurrentTenant currentTenant, + IUnitOfWorkManager unitOfWorkManager, + IAbpDistributedLock abpDistributedLock, + IDistributedEventBus distributedEventBus, + ILoggerFactory loggerFactory) + : base( + ConnectionStringNameAttribute.GetConnStringName(), + currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) + { + DataSeeder = dataSeeder; + } + + protected async override Task SeedAsync(Guid? tenantId) + { + await DataSeeder.SeedAsync(tenantId); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs new file mode 100644 index 000000000..70d5d69e8 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs @@ -0,0 +1,58 @@ +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.Saas.Tenants; +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.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public class ProjectNameDbMigrationService : EfCoreRuntimeDbMigratorBase, ITransientDependency +{ + protected IDataSeeder DataSeeder { get; } + protected IDbSchemaMigrator DbSchemaMigrator { get; } + protected ITenantRepository TenantRepository { get; } + + public ProjectNameDbMigrationService( + IDataSeeder dataSeeder, + IDbSchemaMigrator dbSchemaMigrator, + ITenantRepository tenantRepository, + ICurrentTenant currentTenant, + IUnitOfWorkManager unitOfWorkManager, + IServiceProvider serviceProvider, + IAbpDistributedLock abpDistributedLock, + IDistributedEventBus distributedEventBus, + ILoggerFactory loggerFactory) + : base( + ConnectionStringNameAttribute.GetConnStringName(), + unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) + { + DataSeeder = dataSeeder; + DbSchemaMigrator = dbSchemaMigrator; + TenantRepository = tenantRepository; + } + + protected async override Task LockAndApplyDatabaseMigrationsAsync() + { + await base.LockAndApplyDatabaseMigrationsAsync(); + + var tenants = await TenantRepository.GetListAsync(); + foreach (var tenant in tenants.Where(x => x.IsActive)) + { + await LockAndApplyDatabaseWithTenantMigrationsAsync(tenant.Id); + } + } + + protected async override Task SeedAsync() + { + Logger.LogInformation($"Executing {(!CurrentTenant.IsAvailable ? "host" : CurrentTenant.Name ?? CurrentTenant.GetId().ToString())} database seed..."); + + await DataSeeder.SeedAsync(CurrentTenant.Id); + } +} \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs new file mode 100644 index 000000000..90b369745 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public static class ProjectNameEfCoreQueryableExtensions +{ + // 在此聚合仓储服务的扩展方法 +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs new file mode 100644 index 000000000..b18f43183 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs @@ -0,0 +1,76 @@ +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.DataProtection.EntityFrameworkCore; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; +#if MySQL +using Volo.Abp.EntityFrameworkCore.MySQL; +#elif SqlServer +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Microsoft.EntityFrameworkCore.Infrastructure; +#elif Sqlite +using Volo.Abp.EntityFrameworkCore.Sqlite; +#elif Oracle +using Volo.Abp.EntityFrameworkCore.Oracle; +#elif OracleDevart +using Volo.Abp.EntityFrameworkCore.Oracle.Devart; +#elif PostgreSql +using Volo.Abp.EntityFrameworkCore.PostgreSql; +#endif + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[DependsOn( + typeof(ProjectNameDomainModule), + typeof(AbpDataDbMigratorModule), + typeof(AbpDataProtectionEntityFrameworkCoreModule), +#if MySQL + typeof(AbpEntityFrameworkCoreMySQLModule), +#elif SqlServer + typeof(AbpEntityFrameworkCoreSqlServerModule), +#elif Sqlite + typeof(AbpEntityFrameworkCoreSqliteModule), +#elif Oracle + typeof(AbpEntityFrameworkCoreOracleModule), +#elif OracleDevart + typeof(AbpEntityFrameworkCoreOracleDevartModule), +#elif PostgreSql + typeof(AbpEntityFrameworkCorePostgreSqlModule), +#endif + typeof(AbpSaasEntityFrameworkCoreModule))] +public class ProjectNameEntityFrameworkCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + // 配置Ef + Configure(options => + { +#if MySQL + options.UseMySQL(); + options.UseMySQL(); +#elif SqlServer + options.UseSqlServer(); + options.UseSqlServer(builder => + { + // see https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-ver16 + // builder.UseCompatibilityLevel(150); + }); +#elif Sqlite + options.UseSqlite(); + options.UseSqlite(); +#elif Oracle || OracleDevart + options.UseOracle(); + options.UseOracle(); +#elif PostgreSql + options.UseNpgsql(); + options.UseNpgsql(); +#endif + }); + + context.Services.AddAbpDbContext(options => + { + options.AddDefaultRepositories(); + }); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs new file mode 100644 index 000000000..5849eb902 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; +using Volo.Abp.EntityFrameworkCore.Modeling; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public class ProjectNameModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions +{ + public ProjectNameModelBuilderConfigurationOptions( + [NotNull] string tablePrefix = "", + [CanBeNull] string schema = null) + : base( + tablePrefix, + schema) + { + + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj new file mode 100644 index 000000000..30cf00fd9 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj @@ -0,0 +1,24 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + PackageName.CompanyName.ProjectName.HttpApi.Client + PackageName.CompanyName.ProjectName.HttpApi.Client + false + false + false + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs new file mode 100644 index 000000000..831ba468a --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpHttpClientModule), + typeof(ProjectNameApplicationContractsModule))] +public class ProjectNameHttpApiClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddStaticHttpClientProxies( + typeof(ProjectNameApplicationContractsModule).Assembly, + ProjectNameRemoteServiceConsts.RemoteServiceName); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj new file mode 100644 index 000000000..0f2375f61 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj @@ -0,0 +1,25 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.HttpApi + PackageName.CompanyName.ProjectName.HttpApi + false + false + false + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs new file mode 100644 index 000000000..7345f99ea --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs @@ -0,0 +1,12 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameControllerBase : AbpControllerBase +{ + protected ProjectNameControllerBase() + { + LocalizationResource = typeof(ProjectNameResource); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs new file mode 100644 index 000000000..41cfe834a --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs @@ -0,0 +1,17 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using PackageName.CompanyName.ProjectName.Localization; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 提供动态查询控制器实现 +/// +/// 实体dto类型 +public abstract class ProjectNameDynamicQueryableControllerBase : DynamicQueryableControllerBase +{ + protected ProjectNameDynamicQueryableControllerBase( + IDynamicQueryableAppService service) + : base(service) + { + LocalizationResource = typeof(ProjectNameResource); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs new file mode 100644 index 000000000..3a68e60da --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs @@ -0,0 +1,42 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Validation.Localization; +using LINGYUN.Abp.Dynamic.Queryable; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAspNetCoreMvcModule), + typeof(ProjectNameApplicationContractsModule), + typeof(AbpDynamicQueryableHttpApiModule))] +public class ProjectNameHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(ProjectNameHttpApiModule).Assembly); + }); + + PreConfigure(options => + { + options.AddAssemblyResource( + typeof(ProjectNameResource), + typeof(ProjectNameApplicationContractsModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpValidationResource)); + }); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj new file mode 100644 index 000000000..51af57d0b --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj @@ -0,0 +1,27 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.SettingManagement + PackageName.CompanyName.ProjectName.SettingManagement + false + false + false + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs new file mode 100644 index 000000000..dff74dddb --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs @@ -0,0 +1,7 @@ +using LINGYUN.Abp.SettingManagement; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +public interface IProjectNameSettingAppService : ISettingAppService, IUserSettingAppService +{ +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs new file mode 100644 index 000000000..4fab9bdd6 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs @@ -0,0 +1,106 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Authorization; +using PackageName.CompanyName.ProjectName.Permissions; +using PackageName.CompanyName.ProjectName.Localization; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using Volo.Abp.Features; +using Volo.Abp.MultiTenancy; +using Volo.Abp.SettingManagement; +using Volo.Abp.Settings; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +public class ProjectNameSettingAppService : ApplicationService, IProjectNameSettingAppService +{ + protected ISettingManager SettingManager { get; } + protected ISettingDefinitionManager SettingDefinitionManager { get; } + + public ProjectNameSettingAppService( + ISettingManager settingManager, + ISettingDefinitionManager settingDefinitionManager) + { + SettingManager = settingManager; + SettingDefinitionManager = settingDefinitionManager; + LocalizationResource = typeof(ProjectNameResource); + } + + public virtual async Task GetAllForCurrentTenantAsync() + { + return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString()); + } + + [Authorize] + public virtual async Task GetAllForCurrentUserAsync() + { + return await GetAllForProviderAsync(UserSettingValueProvider.ProviderName, CurrentUser.GetId().ToString()); + } + + public virtual async Task GetAllForGlobalAsync() + { + return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null); + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + if (CurrentTenant.IsAvailable) + { + foreach (var setting in input.Settings) + { + await SettingManager.SetForTenantAsync(CurrentTenant.GetId(), setting.Name, setting.Value); + } + + await CurrentUnitOfWork.SaveChangesAsync(); + } + } + + [Authorize] + public virtual async Task SetCurrentUserAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + foreach (var setting in input.Settings) + { + await SettingManager.SetForCurrentUserAsync(setting.Name, setting.Value); + } + + await CurrentUnitOfWork.SaveChangesAsync(); + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + public virtual async Task SetGlobalAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + foreach (var setting in input.Settings) + { + await SettingManager.SetGlobalAsync(setting.Name, setting.Value); + } + + await CurrentUnitOfWork.SaveChangesAsync(); + } + + + protected virtual async Task CheckFeatureAsync() + { + await FeatureChecker.CheckEnabledAsync(SettingManagementFeatures.Enable); + } + + protected virtual async Task GetAllForProviderAsync(string providerName, string providerKey) + { + var settingGroups = new SettingGroupResult(); + + //TODO: 当前项目所有配置项在此定义返回 + + await Task.CompletedTask; + + return settingGroups; + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs new file mode 100644 index 000000000..2c045ba59 --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs @@ -0,0 +1,69 @@ +using Asp.Versioning; +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using PackageName.CompanyName.ProjectName.Permissions; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +[RemoteService(Name = ProjectNameRemoteServiceConsts.RemoteServiceName)] +[ApiVersion("2.0")] +[Area(ProjectNameRemoteServiceConsts.ModuleName)] +[Route("api/ProjectName/settings")] +public class ProjectNameSettingController : AbpController, IProjectNameSettingAppService +{ + private readonly IProjectNameSettingAppService _settingAppService; + public ProjectNameSettingController(IProjectNameSettingAppService settingAppService) + { + _settingAppService = settingAppService; + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + [HttpPut] + [Route("by-current-tenant")] + public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) + { + await _settingAppService.SetCurrentTenantAsync(input); + } + + [HttpGet] + [Route("by-current-tenant")] + public virtual async Task GetAllForCurrentTenantAsync() + { + return await _settingAppService.GetAllForCurrentTenantAsync(); + } + + [Authorize] + [HttpPut] + [Route("by-current-user")] + public virtual async Task SetCurrentUserAsync(UpdateSettingsDto input) + { + await _settingAppService.SetCurrentTenantAsync(input); + } + + [Authorize] + [HttpGet] + [Route("by-current-user")] + public virtual async Task GetAllForCurrentUserAsync() + { + return await _settingAppService.GetAllForCurrentTenantAsync(); + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + [HttpPut] + [Route("by-global")] + public virtual async Task SetGlobalAsync(UpdateSettingsDto input) + { + await _settingAppService.SetGlobalAsync(input); + } + + [HttpGet] + [Route("by-global")] + public virtual async Task GetAllForGlobalAsync() + { + return await _settingAppService.GetAllForGlobalAsync(); + } +} diff --git a/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs new file mode 100644 index 000000000..914707f4a --- /dev/null +++ b/aspnet-core/templates/micro/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; +using Volo.Abp.SettingManagement; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +[DependsOn( + typeof(AbpSettingManagementApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule), + typeof(AbpSettingManagementDomainModule))] +public class ProjectNameSettingManagementModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(ProjectNameSettingManagementModule).Assembly); + }); + } +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj new file mode 100644 index 000000000..7aefab82c --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + + false + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs new file mode 100644 index 000000000..f5ae45141 --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs @@ -0,0 +1,5 @@ +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameApplicationTestBase : ProjectNameTestBase +{ +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs new file mode 100644 index 000000000..7e9fa658a --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(ProjectNameDomainTestModule), + typeof(ProjectNameApplicationModule) + )] +public class ProjectNameApplicationTestModule : AbpModule +{ +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj new file mode 100644 index 000000000..5ca01ede0 --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + + false + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs new file mode 100644 index 000000000..471e0adf8 --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs @@ -0,0 +1,5 @@ +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameDomainTestBase : ProjectNameTestBase +{ +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs new file mode 100644 index 000000000..f4a8a9d16 --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(ProjectNameTestBaseModule), + typeof(ProjectNameDomainModule) + )] +public class ProjectNameDomainTestModule : AbpModule +{ +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj new file mode 100644 index 000000000..cb9c91e1f --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + + false + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs new file mode 100644 index 000000000..738149b6f --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs @@ -0,0 +1,5 @@ +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public abstract class ProjectNameEntityFrameworkCoreTestBase : ProjectNameTestBase +{ +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs new file mode 100644 index 000000000..da8ce7c6c --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using System; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[DependsOn( + typeof(ProjectNameTestBaseModule), + typeof(ProjectNameEntityFrameworkCoreModule) + )] +public class ProjectNameEntityFrameworkCoreTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddEntityFrameworkInMemoryDatabase(); + + var databaseName = Guid.NewGuid().ToString(); + + Configure(options => + { + options.Configure(abpDbContextConfigurationContext => + { + abpDbContextConfigurationContext.DbContextOptions.EnableDetailedErrors(); + abpDbContextConfigurationContext.DbContextOptions.EnableSensitiveDataLogging(); + + abpDbContextConfigurationContext.DbContextOptions.UseInMemoryDatabase(databaseName); + }); + }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions + }); + } +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj new file mode 100644 index 000000000..ae4b6d5bf --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + + false + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs new file mode 100644 index 000000000..08aeffccb --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs @@ -0,0 +1,58 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Modularity; +using Volo.Abp.Testing; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected virtual Task WithUnitOfWorkAsync(Func func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + await action(); + + await uow.CompleteAsync(); + } + } + } + + protected virtual Task WithUnitOfWorkAsync(Func> func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + var result = await func(); + await uow.CompleteAsync(); + return result; + } + } + } +} diff --git a/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs new file mode 100644 index 000000000..4564d29b6 --- /dev/null +++ b/aspnet-core/templates/micro/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.Features; +using Volo.Abp.MemoryDb; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpTestBaseModule), + typeof(AbpAuthorizationModule), + typeof(AbpFeaturesModule), + typeof(AbpMemoryDbModule) + )] +public class ProjectNameTestBaseModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAlwaysAllowAuthorization(); + } +} From 27768b73f242da813740579f9fe98cf7f30078f3 Mon Sep 17 00:00:00 2001 From: feijie Date: Mon, 30 Dec 2024 00:27:58 +0800 Subject: [PATCH 14/29] =?UTF-8?q?=E2=9C=A8=20feat(aspnet-core/templates/ai?= =?UTF-8?q?o):=20=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=8A=9F=E8=83=BD=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E9=A1=B9=E7=9B=AE=E6=96=87=E4=BB=B6=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20.NET=208.0=20=E7=89=88=E6=9C=AC=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ageName.CompanyName.ProjectName.AIO.csproj | 30 + .../content/.template.config/template.json | 115 +++ .../.template.config/template.zh-Hans.json | 5 + .../aio/content/Directory.Build.props | 13 + .../aio/content/Directory.Packages.props | 490 +++++++++ .../templates/aio/content/NuGet.Config | 12 + aspnet-core/templates/aio/content/README.md | 129 +++ .../templates/aio/content/README.zh-CN.md | 129 +++ .../templates/aio/content/common.props | 38 + .../aio/content/configureawait.props | 9 + .../.config/dotnet-tools.json | 12 + .../.gitignore | 2 + .../AbpCookieAuthenticationHandler.cs | 89 ++ .../BackgroundJobs/NotificationPublishJob.cs | 38 + .../NotificationPublishJobArgs.cs | 22 + .../Controllers/HomeController.cs | 11 + .../Controllers/SettingMergeController.cs | 70 ++ .../Controllers/UserSettingMergeController.cs | 45 + .../Dockerfile | 19 + .../Distributed/ChatMessageEventHandler.cs | 59 ++ .../Distributed/NotificationEventHandler.cs | 470 +++++++++ .../Distributed/TenantSynchronizer.cs | 53 + .../Distributed/UserCreateEventHandler.cs | 30 + .../Distributed/WebhooksEventHandler.cs | 112 +++ .../Local/UserCreateJoinIMEventHandler.cs | 58 ++ .../UserCreateSendWelcomeEventHandler.cs | 69 ++ .../CustomIdentityResources.cs | 19 + ...rviceApplicationsSingleModule.Configure.cs | 935 ++++++++++++++++++ .../MicroServiceApplicationsSingleModule.cs | 394 ++++++++ ...eSiteCookiesServiceCollectionExtensions.cs | 67 ++ .../MultiTenancy/ITenantConfigurationCache.cs | 10 + .../MultiTenancy/TenantConfigurationCache.cs | 59 ++ .../TenantConfigurationCacheItem.cs | 19 + ...me.CompanyName.ProjectName.AIO.Host.csproj | 276 ++++++ .../PersonalInfo/Default.cshtml | 103 ++ .../PersonalInfo/Default.js | 28 + .../Pages/Account/EmailConfirm.cshtml | 17 + .../Pages/Account/EmailConfirm.cshtml.cs | 72 ++ .../Account/EmailConfirmConfirmation.cshtml | 13 + .../EmailConfirmConfirmation.cshtml.cs | 22 + .../Pages/Account/SendCode.cshtml | 26 + .../Pages/Account/SendCode.cshtml.cs | 125 +++ .../Pages/Account/SendEmailConfirm.cshtml | 16 + .../Pages/Account/SendEmailConfirm.cshtml.cs | 73 ++ .../Account/TwoFactorSupportedLoginModel.cs | 63 ++ .../Pages/Account/UseRecoveryCode.cshtml | 4 + .../Pages/Account/UseRecoveryCode.cshtml.cs | 11 + .../Account/VerifyAuthenticatorCode.cshtml | 26 + .../Account/VerifyAuthenticatorCode.cshtml.cs | 59 ++ .../Pages/Account/VerifyCode.cshtml | 29 + .../Pages/Account/VerifyCode.cshtml.cs | 90 ++ .../Pages/Index.cshtml | 36 + .../Pages/Index.cshtml.cs | 11 + .../Pages/_ViewImports.cshtml | 4 + .../Program.cs | 82 ++ .../Properties/launchSettings.json | 30 + .../TenantHeaderParamter.cs | 35 + .../Messages/TextMessageReplyContributor.cs | 21 + .../Messages/UserSubscribeEventContributor.cs | 21 + .../Messages/TextMessageReplyContributor.cs | 24 + .../appsettings.Development.json | 249 +++++ .../appsettings.json | 89 ++ .../gulpfile.js | 10 + ...panyName.ProjectName.AIO.DbMigrator.csproj | 54 + .../Program.cs | 44 + .../README.EN.md | 75 ++ .../README.md | 75 ++ .../SingleDbMigratorHostedService.cs | 51 + .../SingleDbMigratorModule.Configure.cs | 14 + .../SingleDbMigratorModule.cs | 22 + .../Usings.cs | 7 + .../appsettings.MySql.json | 228 +++++ .../appsettings.PostgreSql.json | 228 +++++ .../appsettings.SqlServer.json | 228 +++++ .../appsettings.json | 104 ++ .../FodyWeavers.xml | 4 + .../FodyWeavers.xsd | 30 + ...tName.AIO.EntityFrameworkCore.MySql.csproj | 22 + .../README.en.md | 59 ++ .../README.md | 59 ++ .../SingleMigrationsDbContextFactory.cs | 32 + ...igrationsEntityFrameworkCoreMySqlModule.cs | 24 + .../DataSeeder/ClientDataSeederContributor.cs | 469 +++++++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...ProjectName.AIO.EntityFrameworkCore.csproj | 47 + .../README.EN.md | 97 ++ .../README.md | 97 ++ .../SingleDbMigrationEventHandler.cs | 242 +++++ .../SingleDbMigrationService.cs | 101 ++ .../SingleMigrationsDbContext.cs | 58 ++ ...ngleMigrationsEntityFrameworkCoreModule.cs | 48 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...e.ProjectName.Application.Contracts.csproj | 27 + .../ProjectNameFeatureDefinitionProvider.cs | 18 + .../Features/ProjectNameFeatureNames.cs | 6 + .../IProjectNameDynamicQueryableAppService.cs | 10 + ...ProjectNamePermissionDefinitionProvider.cs | 22 + .../Permissions/ProjectNamePermissions.cs | 8 + .../ProjectNameApplicationContractsModule.cs | 17 + .../ProjectNameRemoteServiceConsts.cs | 7 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...CompanyName.ProjectName.Application.csproj | 26 + .../ProjectName/ProjectNameAppServiceBase.cs | 13 + .../ProjectNameApplicationMapperProfile.cs | 10 + .../ProjectNameApplicationModule.cs | 27 + ...ojectNameDynamicQueryableAppServiceBase.cs | 19 + .../Expressions/ExpressionFuncExtensions.cs | 32 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...CompanyName.ProjectName.Dapr.Client.csproj | 19 + .../ProjectNameDaprClientModule.cs | 18 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...mpanyName.ProjectName.Domain.Shared.csproj | 30 + .../Localization/ProjectNameResource.cs | 8 + .../Localization/Resources/en.json | 8 + .../Localization/Resources/zh-Hans.json | 8 + ...ProjectNameModuleExtensionConfiguration.cs | 16 + ...ensionConfigurationDictionaryExtensions.cs | 19 + .../ProjectNameModuleExtensionConsts.cs | 11 + .../ProjectNameDomainSharedModule.cs | 32 + .../ProjectName/ProjectNameErrorCodes.cs | 6 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...Name.CompanyName.ProjectName.Domain.csproj | 27 + .../IProjectNameBasicRepository.cs | 54 + .../ProjectName/ProjectNameDbProperties.cs | 11 + .../ProjectNameDomainMapperProfile.cs | 11 + .../ProjectName/ProjectNameDomainModule.cs | 45 + .../ProjectNameSettingDefinitionProvider.cs | 10 + .../Settings/ProjectNameSettings.cs | 6 + .../Expressions/ExpressionFuncExtensions.cs | 32 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...ame.ProjectName.EntityFrameworkCore.csproj | 37 + .../EfCoreProjectNameRepository.cs | 77 ++ .../IProjectNameDbContext.cs | 9 + .../ProjectNameDbContext.cs | 21 + .../ProjectNameDbContextFactory.cs | 49 + ...ectNameDbContextModelCreatingExtensions.cs | 21 + .../ProjectNameDbMigrationEventHandler.cs | 36 + .../ProjectNameDbMigrationService.cs | 58 ++ .../ProjectNameEfCoreQueryableExtensions.cs | 6 + .../ProjectNameEntityFrameworkCoreModule.cs | 76 ++ ...ectNameModelBuilderConfigurationOptions.cs | 17 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...panyName.ProjectName.HttpApi.Client.csproj | 24 + .../ProjectNameHttpApiClientModule.cs | 18 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...ame.CompanyName.ProjectName.HttpApi.csproj | 25 + .../ProjectName/ProjectNameControllerBase.cs | 12 + ...ojectNameDynamicQueryableControllerBase.cs | 17 + .../ProjectName/ProjectNameHttpApiModule.cs | 42 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 + ...yName.ProjectName.SettingManagement.csproj | 27 + .../IProjectNameSettingAppService.cs | 7 + .../ProjectNameSettingAppService.cs | 106 ++ .../ProjectNameSettingController.cs | 69 ++ .../ProjectNameSettingManagementModule.cs | 22 + ...yName.ProjectName.Application.Tests.csproj | 18 + .../ProjectNameApplicationTestBase.cs | 5 + .../ProjectNameApplicationTestModule.cs | 11 + ...ompanyName.ProjectName.Domain.Tests.csproj | 18 + .../ProjectName/ProjectNameDomainTestBase.cs | 5 + .../ProjectNameDomainTestModule.cs | 11 + ...ojectName.EntityFrameworkCore.Tests.csproj | 19 + .../ProjectNameEntityFrameworkCoreTestBase.cs | 5 + ...rojectNameEntityFrameworkCoreTestModule.cs | 38 + ...me.CompanyName.ProjectName.TestBase.csproj | 23 + .../ProjectName/ProjectNameTestBase.cs | 58 ++ .../ProjectName/ProjectNameTestBaseModule.cs | 24 + 177 files changed, 9770 insertions(+) create mode 100644 aspnet-core/templates/aio/PackageName.CompanyName.ProjectName.AIO.csproj create mode 100644 aspnet-core/templates/aio/content/.template.config/template.json create mode 100644 aspnet-core/templates/aio/content/.template.config/template.zh-Hans.json create mode 100644 aspnet-core/templates/aio/content/Directory.Build.props create mode 100644 aspnet-core/templates/aio/content/Directory.Packages.props create mode 100644 aspnet-core/templates/aio/content/NuGet.Config create mode 100644 aspnet-core/templates/aio/content/README.md create mode 100644 aspnet-core/templates/aio/content/README.zh-CN.md create mode 100644 aspnet-core/templates/aio/content/common.props create mode 100644 aspnet-core/templates/aio/content/configureawait.props create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json create mode 100644 aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Usings.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs create mode 100644 aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs create mode 100644 aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs diff --git a/aspnet-core/templates/aio/PackageName.CompanyName.ProjectName.AIO.csproj b/aspnet-core/templates/aio/PackageName.CompanyName.ProjectName.AIO.csproj new file mode 100644 index 000000000..88bfabf98 --- /dev/null +++ b/aspnet-core/templates/aio/PackageName.CompanyName.ProjectName.AIO.csproj @@ -0,0 +1,30 @@ + + + net8.0 + true + LINGYUN.Abp.AllInOne.Templates + 8.3.0 + colin.in@foxmail.com + Abp framework all-in-one template + MIT + false + https://github.com/colinin/abp-next-admin + allinone webapi cloud + Template + git + https://github.com/colinin/abp-next-admin + true + true + true + true + False + False + + + + + true + content + + + diff --git a/aspnet-core/templates/aio/content/.template.config/template.json b/aspnet-core/templates/aio/content/.template.config/template.json new file mode 100644 index 000000000..b2a850a12 --- /dev/null +++ b/aspnet-core/templates/aio/content/.template.config/template.json @@ -0,0 +1,115 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "colin.in@foxmail.com", + "classifications": ["allinone", "webapi", "cloud"], + "name": "LINGYUN.Abp.AllInOne", + "identity": "LINGYUN.Abp.AllInOne", + "description": "Abp framework all-in-one template", + "groupIdentity": "LINGYUN.Abp.Application", + "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\")" + } + } +} diff --git a/aspnet-core/templates/aio/content/.template.config/template.zh-Hans.json b/aspnet-core/templates/aio/content/.template.config/template.zh-Hans.json new file mode 100644 index 000000000..f0339e4e4 --- /dev/null +++ b/aspnet-core/templates/aio/content/.template.config/template.zh-Hans.json @@ -0,0 +1,5 @@ +{ + "description": "适用于abp框架的微服务模板项目", + "symbols/AuthenticationScheme/description": "认证服务体系, 可选项为: IdentityServer4、OpenIddict, 默认使用IdentityServer4.", + "symbols/DatabaseManagement/description": "数据库管理提供者, 可选项为: SqlServer、MySQL、Sqlite、Oracle、OracleDevart、PostgreSql, 默认使用MySQL." +} diff --git a/aspnet-core/templates/aio/content/Directory.Build.props b/aspnet-core/templates/aio/content/Directory.Build.props new file mode 100644 index 000000000..6f2501679 --- /dev/null +++ b/aspnet-core/templates/aio/content/Directory.Build.props @@ -0,0 +1,13 @@ + + + true + + + + + all + runtime; build; native; contentfiles; analyzers + + + + diff --git a/aspnet-core/templates/aio/content/Directory.Packages.props b/aspnet-core/templates/aio/content/Directory.Packages.props new file mode 100644 index 000000000..433f06afb --- /dev/null +++ b/aspnet-core/templates/aio/content/Directory.Packages.props @@ -0,0 +1,490 @@ + + + 8.2.0 + 2.14.1 + 8.3.0 + 8.3.0 + 8.0.0 + 8.0.0 + 8.0.0 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/NuGet.Config b/aspnet-core/templates/aio/content/NuGet.Config new file mode 100644 index 000000000..ddde6944c --- /dev/null +++ b/aspnet-core/templates/aio/content/NuGet.Config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/README.md b/aspnet-core/templates/aio/content/README.md new file mode 100644 index 000000000..7b7520aef --- /dev/null +++ b/aspnet-core/templates/aio/content/README.md @@ -0,0 +1,129 @@ +# 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 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) +dotnet new lam -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +``` + +#### For All-in-One Project + +```bash +# Short name: laa (LINGYUN Abp AllInOne) +dotnet new laa -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;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 +cd /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 +8.3.0 +``` + +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 diff --git a/aspnet-core/templates/aio/content/README.zh-CN.md b/aspnet-core/templates/aio/content/README.zh-CN.md new file mode 100644 index 000000000..b93d76220 --- /dev/null +++ b/aspnet-core/templates/aio/content/README.zh-CN.md @@ -0,0 +1,129 @@ +# LINGYUN.Abp.Templates + +[English](README.md) | [中文](README.zh-CN.md) + +## 简介 + +LINGYUN.Abp.Templates 基于 ABP Framework 提供两种项目模板: + +1. **微服务模板**:完整的分布式微服务架构模板 +2. **单体应用模板**:将所有服务集成到一个项目中的单体应用模板 + +## 特性 + +### 共同特性 + +- 集成身份认证(支持 IdentityServer4/OpenIddict) +- 数据库集成(支持多种数据库) +- 统一配置管理 +- 分布式事件总线支持 +- 后台作业处理 + +### 微服务模板特性 + +- 完整的微服务项目结构 +- 服务发现与注册 +- 支持分布式部署 + +### 单体应用模板特性 + +- 简化的部署流程 +- 更容易的维护 +- 更低的资源需求 + +## 使用方法 + +### 安装模板 + +```bash +# 安装微服务模板 +dotnet new install LINGYUN.Abp.MicroService.Templates + +# 安装单体应用模板 +dotnet new install LINGYUN.Abp.AllInOne.Templates +``` + +### 创建新项目 + +#### 创建微服务项目 + +```bash +# 简写名称:lam (LINGYUN Abp Microservice) +dotnet new lam -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +``` + +#### 创建单体应用项目 + +```bash +# 简写名称:laa (LINGYUN Abp AllInOne) +labp create MyCompanyName.MyProjectName -pk MyPackageName -t laa -o /Users/feijie/Projects/Tests --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port +``` + +## 运行项目 + +创建项目后,可以使用以下命令运行: + +### 运行微服务项目 + +```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 +cd /aspnet-core/templates/content +``` + +2. 修改版本号 + 编辑项目文件更新版本号: + - 微服务模板:`../PackageName.CompanyName.ProjectName.csproj` + - 单体应用模板:`../PackageName.CompanyName.ProjectName.AIO.csproj` + +```xml +8.3.0 +``` + +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 发布地址和密钥 +- 发布前建议进行完整测试 diff --git a/aspnet-core/templates/aio/content/common.props b/aspnet-core/templates/aio/content/common.props new file mode 100644 index 000000000..d7d7622cf --- /dev/null +++ b/aspnet-core/templates/aio/content/common.props @@ -0,0 +1,38 @@ + + + latest + 8.2.1 + colin + $(NoWarn);CS1591;CS0436;CS8618;NU1803 + https://github.com/colinin/abp-next-admin + $(SolutionDir)LocalNuget + 8.2.1 + MIT + git + https://github.com/colinin/abp-next-admin + true + + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)LocalNuget + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/configureawait.props b/aspnet-core/templates/aio/content/configureawait.props new file mode 100644 index 000000000..3caa88c04 --- /dev/null +++ b/aspnet-core/templates/aio/content/configureawait.props @@ -0,0 +1,9 @@ + + + + + All + runtime; build; native; contentfiles; analyzers + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json new file mode 100644 index 000000000..6b93cca86 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "7.0.3", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore new file mode 100644 index 000000000..7b6f60857 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/.gitignore @@ -0,0 +1,2 @@ +wwwroot +package*.json \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs new file mode 100644 index 000000000..34517090f --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Authentication/AbpCookieAuthenticationHandler.cs @@ -0,0 +1,89 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.Extensions.Options; +using System.Text.Encodings.Web; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Authentication; + +public class AbpCookieAuthenticationHandler : CookieAuthenticationHandler +{ + public AbpCookieAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder) : base(options, logger, encoder) + { + } + + public AbpCookieAuthenticationHandler( + IOptionsMonitor 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; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs new file mode 100644 index 000000000..c9db9977a --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJob.cs @@ -0,0 +1,38 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Options; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs; + +public class NotificationPublishJob : AsyncBackgroundJob, ITransientDependency +{ + protected AbpNotificationsPublishOptions Options { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } + protected INotificationDataSerializer NotificationDataSerializer { get; } + public NotificationPublishJob( + IOptions 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(); + var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); + notification.Data = NotificationDataSerializer.Serialize(notification.Data); + + await publishProvider.PublishAsync(notification, args.UserIdentifiers); + } + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs new file mode 100644 index 000000000..e5f077d65 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/BackgroundJobs/NotificationPublishJobArgs.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.Notifications; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs; + +public class NotificationPublishJobArgs +{ + public Guid? TenantId { get; set; } + public long NotificationId { get; set; } + public string ProviderType { get; set; } + public List UserIdentifiers { get; set; } + public NotificationPublishJobArgs() + { + UserIdentifiers = new List(); + } + public NotificationPublishJobArgs(long id, string providerType, List userIdentifiers, Guid? tenantId = null) + { + NotificationId = id; + ProviderType = providerType; + UserIdentifiers = userIdentifiers; + TenantId = tenantId; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs new file mode 100644 index 000000000..e693a0917 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/HomeController.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; + +public class HomeController : Controller +{ + public IActionResult Index() + { + return Redirect("/swagger"); + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs new file mode 100644 index 000000000..11e91bd88 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/SettingMergeController.cs @@ -0,0 +1,70 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; + +[ExposeServices( + typeof(SettingController), + typeof(SettingMergeController))] +public class SettingMergeController : SettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public SettingMergeController( + ISettingAppService settingAppService, + ISettingTestAppService settingTestAppService, + IOptions mergeOptions) + : base(settingAppService, settingTestAppService) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-tenant")] + public async override Task GetAllForCurrentTenantAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + 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 GetAllForGlobalAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForGlobalAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs new file mode 100644 index 000000000..5091a8a5e --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Controllers/UserSettingMergeController.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Controllers; + +[ExposeServices( + typeof(UserSettingController), + typeof(UserSettingMergeController))] +public class UserSettingMergeController : UserSettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public UserSettingMergeController( + IUserSettingAppService service, + IOptions mergeOptions) + : base(service) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-user")] + public async override Task GetAllForCurrentUserAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(UserSettingMergeController), + }; + foreach (var serviceType in _mergeOptions.UserSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentUserAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile new file mode 100644 index 000000000..aee09fd66 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile @@ -0,0 +1,19 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +LABEL maintainer="colin.in@foxmail.com" +WORKDIR /app + +COPY . /app + +#东8区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone + +EXPOSE 80/tcp +VOLUME [ "./app/blobs" ] +VOLUME [ "./app/Logs" ] +VOLUME [ "./app/Modules" ] + +RUN apt update +RUN apt install wget -y + +ENTRYPOINT ["dotnet", "LY.MicroService.Applications.Single.dll"] diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs new file mode 100644 index 000000000..a08702a0a --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/ChatMessageEventHandler.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.IM; +using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.RealTime; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + public class ChatMessageEventHandler : IDistributedEventHandler>, ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpIMOptions Options { get; } + + protected IMessageStore MessageStore { get; } + protected IMessageBlocker MessageBlocker { get; } + protected IMessageSenderProviderManager MessageSenderProviderManager { get; } + + public ChatMessageEventHandler( + IOptions options, + IMessageStore messageStore, + IMessageBlocker messageBlocker, + IMessageSenderProviderManager messageSenderProviderManager) + { + Options = options.Value; + MessageStore = messageStore; + MessageBlocker = messageBlocker; + MessageSenderProviderManager = messageSenderProviderManager; + + Logger = NullLogger.Instance; + } + + public async virtual Task HandleEventAsync(RealTimeEto 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); + } + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs new file mode 100644 index 000000000..cb871c6ef --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/NotificationEventHandler.cs @@ -0,0 +1,470 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using PackageName.CompanyName.ProjectName.AIO.Host.BackgroundJobs; +using PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; +using System.Globalization; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Json; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.TextTemplating; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + /// + /// 订阅通知发布事件,统一发布消息 + /// + /// + /// 作用在于SignalR客户端只会与一台服务器建立连接, + /// 只有启用了SignlR服务端的才能真正将消息发布到客户端 + /// + public class NotificationEventHandler : + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpNotificationsPublishOptions Options { get; } + /// + /// Reference to . + /// + protected ICurrentTenant CurrentTenant { get; } + /// + /// Reference to . + /// + protected ITenantConfigurationCache TenantConfigurationCache { get; } + /// + /// Reference to . + /// + protected IJsonSerializer JsonSerializer { get; } + /// + /// Reference to . + /// + protected IBackgroundJobManager BackgroundJobManager { get; } + /// + /// Reference to . + /// + protected ITemplateRenderer TemplateRenderer { get; } + /// + /// Reference to . + /// + protected INotificationStore NotificationStore { get; } + /// + /// Reference to . + /// + protected IStringLocalizerFactory StringLocalizerFactory { get; } + /// + /// Reference to . + /// + protected INotificationDataSerializer NotificationDataSerializer { get; } + /// + /// Reference to . + /// + protected INotificationDefinitionManager NotificationDefinitionManager { get; } + /// + /// Reference to . + /// + protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } + /// + /// Reference to . + /// + protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } + + /// + /// Initializes a new instance of the class. + /// + public NotificationEventHandler( + ICurrentTenant currentTenant, + ITenantConfigurationCache tenantConfigurationCache, + IJsonSerializer jsonSerializer, + ITemplateRenderer templateRenderer, + IBackgroundJobManager backgroundJobManager, + IStringLocalizerFactory stringLocalizerFactory, + IOptions 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.Instance; + } + + [UnitOfWork] + public async virtual Task HandleEventAsync(NotificationEto 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 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 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 + { + // 模板不支持 $ 字符, 改为普通关键字 + { 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 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); + } + } + } + } + /// + /// 获取用户订阅列表 + /// + /// 通知名称 + /// 接收用户列表 + /// 租户标识 + /// 用户订阅列表 + protected async Task> GerSubscriptionUsersAsync( + string notificationName, + IEnumerable 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(); + } + /// + /// 持久化通知并返回订阅用户列表 + /// + /// 通知实体 + /// 订阅用户列表 + /// 通知发送提供者 + /// 返回订阅者列表 + protected async Task PersistentNotificationAsync( + NotificationInfo notificationInfo, + IEnumerable subscriptionUsers, + IEnumerable 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); + } + } + } + /// + /// 发布订阅者通知 + /// + /// 通知发布者 + /// 通知信息 + /// 订阅用户列表 + /// + protected async Task PublishToSubscriberAsync( + INotificationPublishProvider provider, + NotificationInfo notificationInfo, + IEnumerable 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); + } + } + /// + /// 处理失败的消息进入后台队列 + /// + /// + /// 注: 如果入队失败,消息将被丢弃. + /// + /// + /// + /// + /// + protected async Task ProcessingFailedToQueueAsync( + INotificationPublishProvider provider, + NotificationInfo notificationInfo, + IEnumerable 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); + } + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs new file mode 100644 index 000000000..3e07d5be9 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/TenantSynchronizer.cs @@ -0,0 +1,53 @@ +using LINGYUN.Abp.Saas.Tenants; +using PackageName.CompanyName.ProjectName.AIO.Host.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 PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + public class TenantSynchronizer : + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler>, + IDistributedEventHandler, + 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 eventData) + { + await TenantConfigurationCache.RefreshAsync(); + + await DataSeeder.SeedAsync(eventData.Entity.Id); + } + + public async virtual Task HandleEventAsync(EntityUpdatedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + + public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) + { + await TenantConfigurationCache.RefreshAsync(); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs new file mode 100644 index 000000000..ee5ab700b --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/UserCreateEventHandler.cs @@ -0,0 +1,30 @@ +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.EventBus.Local; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed +{ + public class UserCreateEventHandler : IDistributedEventHandler>, ITransientDependency + { + private readonly ILocalEventBus _localEventBus; + public UserCreateEventHandler( + ILocalEventBus localEventBus) + { + _localEventBus = localEventBus; + } + /// + /// 接收添加用户事件,发布本地事件 + /// + /// + /// + public async Task HandleEventAsync(EntityCreatedEto eventData) + { + var localUserCreateEventData = new EntityCreatedEventData(eventData.Entity); + + await _localEventBus.PublishAsync(localUserCreateEventData); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs new file mode 100644 index 000000000..eeb0fcdb7 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Distributed/WebhooksEventHandler.cs @@ -0,0 +1,112 @@ +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.Webhooks.EventBus; +using Volo.Abp.BackgroundJobs; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Distributed; + +public class WebhooksEventHandler : + IDistributedEventHandler, + 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 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 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; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs new file mode 100644 index 000000000..2b78e5841 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs @@ -0,0 +1,58 @@ +using LINGYUN.Abp.MessageService.Chat; +using LINGYUN.Abp.MessageService.Notifications; +using LINGYUN.Abp.Notifications; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.Uow; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Local +{ + public class UserCreateJoinIMEventHandler : ILocalEventHandler>, ITransientDependency + { + private readonly IChatDataSeeder _chatDataSeeder; + private readonly INotificationSubscriptionManager _notificationSubscriptionManager; + public UserCreateJoinIMEventHandler( + IChatDataSeeder chatDataSeeder, + INotificationSubscriptionManager notificationSubscriptionManager) + { + _chatDataSeeder = chatDataSeeder; + _notificationSubscriptionManager = notificationSubscriptionManager; + } + /// + /// 接收添加用户事件,初始化IM用户种子 + /// + /// + /// + [UnitOfWork] + public async virtual Task HandleEventAsync(EntityCreatedEventData 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); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs new file mode 100644 index 000000000..8176df498 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs @@ -0,0 +1,69 @@ +using LINGYUN.Abp.Notifications; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.EventBus.Local +{ + public class UserCreateSendWelcomeEventHandler : ILocalEventHandler>, ITransientDependency + { + private readonly INotificationSender _notificationSender; + private readonly INotificationSubscriptionManager _notificationSubscriptionManager; + public UserCreateSendWelcomeEventHandler( + INotificationSender notificationSender, + INotificationSubscriptionManager notificationSubscriptionManager + ) + { + _notificationSender = notificationSender; + _notificationSubscriptionManager = notificationSubscriptionManager; + } + + public async Task HandleEventAsync(EntityCreatedEventData 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 + { + { "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); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs new file mode 100644 index 000000000..99fce8c22 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/IdentityResources/CustomIdentityResources.cs @@ -0,0 +1,19 @@ +using LINGYUN.Abp.Identity; +using IdentityServer4.Models; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 }; + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs new file mode 100644 index 000000000..cbc4e883a --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs @@ -0,0 +1,935 @@ +using Elsa; +using Elsa.Options; +using LINGYUN.Abp.Aliyun.Localization; +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.DataProtectionManagement; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Exporter.MiniExcel; +using LINGYUN.Abp.Idempotent; +using LINGYUN.Abp.Identity.Session; +using LINGYUN.Abp.IdentityServer.IdentityResources; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Notifications; +using LINGYUN.Abp.OpenIddict.AspNetCore.Session; +using LINGYUN.Abp.OpenIddict.LinkUser; +using LINGYUN.Abp.OpenIddict.Permissions; +using LINGYUN.Abp.OpenIddict.Portal; +using LINGYUN.Abp.OpenIddict.Sms; +using LINGYUN.Abp.OpenIddict.WeChat; +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.Tencent.Localization; +using LINGYUN.Abp.TextTemplating; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Localization; +using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.Wrapper; +using LINGYUN.Platform.Localization; +using PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection; +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 PackageName.CompanyName.ProjectName.AIO.Host.Authentication; +using PackageName.CompanyName.ProjectName.AIO.Host.IdentityResources; +using PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; +using Quartz; +using StackExchange.Redis; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +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 PackageName.CompanyName.ProjectName.AIO.Host; + +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(options => + { + // 以开放端口区别,应在0-31之间 + options.SnowflakeIdOptions.WorkerId = 1; + options.SnowflakeIdOptions.WorkerIdBits = 5; + options.SnowflakeIdOptions.DatacenterId = 1; + }); + + if (configuration.GetValue("App:ShowPii")) + { + IdentityModelEventSource.ShowPII = true; + } + } + + private void PreConfigureAuthServer(IConfiguration configuration) + { + PreConfigure(builder => + { + builder.AddValidation(options => + { + //options.AddAudiences("lingyun-abp-application"); + + options.UseLocalServer(); + + options.UseAspNetCore(); + + options.UseDataProtection(); + }); + }); + } + + private void PreConfigureIdentity() + { + PreConfigure(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("AuthServer:UseOpenIddict")) + { + PreConfigure(options => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(builder => + { + builder.AddSigningCertificate(certificate); + builder.AddEncryptionCertificate(certificate); + + builder.UseDataProtection(); + + // 禁用https + builder.UseAspNetCore() + .DisableTransportSecurityRequirement(); + }); + } + else + { + PreConfigure(options => + { + options.AddDeveloperSigningCredential = false; + }); + + PreConfigure(builder => + { + builder.AddSigningCredential(certificate); + }); + } + } + } + else + { + if (configuration.GetValue("AuthServer:UseOpenIddict")) + { + PreConfigure(options => + { + //https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + options.AddDevelopmentEncryptionAndSigningCertificate = false; + }); + + PreConfigure(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(options => + { + // 如果使用持久化存储, 则配置quartz持久层 + if (configuration.GetSection("Quartz:UsePersistentStore").Get()) + { + var settings = configuration.GetSection("Quartz:Properties").Get>(); + 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(elsa => + { + elsa + .AddActivitiesFrom() + .AddWorkflowsFrom() + .AddFeatures(startups, configuration) + .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)); + + elsa.DistributedLockingOptionsBuilder + .UseProviderFactory(sp => name => + { + var provider = sp.GetRequiredService(); + + return provider.CreateLock(name); + }); + }); + + services.AddNotificationHandlersFrom(); + + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(Elsa.Webhooks.Api.Endpoints.List).Assembly); + }); + } + + private void ConfigureAuthServer(IConfiguration configuration) + { + Configure(builder => + { + builder.DisableTransportSecurityRequirement(); + }); + + Configure(options => + { + options.DisableTransportSecurityRequirement = true; + }); + + Configure(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(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(options => + //{ + // options.EndpointConfigureActions.Add( + // (context) => + // { + // context.Endpoints.MapFallbackToPage("/_Host"); + // }); + //}); + var preActions = services.GetPreConfigureActions(); + + 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(options => + { + options.Limits.MaxRequestBodySize = null; + options.Limits.MaxRequestBufferSize = null; + }); + } + + private void ConfigureBlobStoring(IConfiguration configuration) + { + Configure(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(options => + { + options.NodeName = ApplicationName; + options.JobCleanEnabled = true; + options.JobFetchEnabled = true; + options.JobCheckEnabled = true; + }); + } + + private void ConfigureTextTemplating(IConfiguration configuration) + { + if (configuration.GetValue("TextTemplating:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicTemplateDefinitionStoreEnabled = true; + }); + } + } + + private void ConfigureFeatureManagement(IConfiguration configuration) + { + if (configuration.GetValue("FeatureManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicFeatureStoreEnabled = true; + }); + } + Configure(options => + { + options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = AbpSaasPermissions.Editions.ManageFeatures; + options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = AbpSaasPermissions.Tenants.ManageFeatures; + }); + } + + private void ConfigureSettingManagement(IConfiguration configuration) + { + if (configuration.GetValue("SettingManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicSettingStoreEnabled = true; + }); + } + } + + private void ConfigureWebhooksManagement(IConfiguration configuration) + { + if (configuration.GetValue("WebhooksManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicWebhookStoreEnabled = true; + }); + } + } + /// + /// 配置数据导出 + /// + private void ConfigureExporter() + { + Configure(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 }, + // }; + // }); + }); + } + /// + /// 配置数据权限 + /// + private void ConfigureEntityDataProtected() + { + // Configure(options => + // { + // options.AddEntities(typeof(DemoResource), + // new[] + // { + // typeof(Book), + // }); + // }); + } + + private void ConfigurePermissionManagement(IConfiguration configuration) + { + if (configuration.GetValue("PermissionManagement:IsDynamicStoreEnabled")) + { + Configure(options => + { + options.IsDynamicPermissionStoreEnabled = true; + }); + } + Configure(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("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("NotificationsManagement:IsDynamicStoreEnabled")) + { + Configure(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(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); + } + } + + private void ConfigureVirtualFileSystem() + { + Configure(options => + { + options.FileSets.AddEmbedded("LY.MicroService.Applications.Single"); + }); + } + + private void ConfigureIdempotent() + { + Configure(options => + { + options.IsEnabled = true; + options.DefaultTimeout = 0; + }); + } + + private void ConfigureDbContext() + { + Configure(options => + { + // AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + // options.UseNpgsql(); + + options.UseMySQL(); + }); + } + + private void ConfigureDataSeeder() + { + Configure(options => + { + options.Resources.Add(new CustomIdentityResources.AvatarUrl()); + }); + } + + private void ConfigureExceptionHandling() + { + // 自定义需要处理的异常 + Configure(options => + { + // 加入需要处理的异常类型 + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + options.Handlers.Add(); + }); + // 自定义需要发送邮件通知的异常类型 + Configure(options => + { + // 是否发送堆栈信息 + options.SendStackTrace = true; + // 未指定异常接收者的默认接收邮件 + // 指定自己的邮件地址 + }); + + Configure(options => + { + options.SendStackTraceToClients = false; + options.SendExceptionsDetailsToClients = false; + }); + } + + private void ConfigureJsonSerializer(IConfiguration configuration) + { + // 统一时间日期格式 + Configure(options => + { + var jsonConfiguration = configuration.GetSection("Json"); + if (jsonConfiguration.Exists()) + { + jsonConfiguration.Bind(options); + } + }); + // 中文序列化的编码问题 + Configure(options => + { + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + }); + } + + private void ConfigureCaching(IConfiguration configuration) + { + Configure(options => + { + configuration.GetSection("DistributedCache").Bind(options); + }); + + Configure(options => + { + var redisConfig = ConfigurationOptions.Parse(options.Configuration); + options.ConfigurationOptions = redisConfig; + options.InstanceName = configuration["Redis:InstanceName"]; + }); + } + + private void ConfigureMultiTenancy(IConfiguration configuration) + { + // 多租户 + Configure(options => + { + options.IsEnabled = true; + }); + + var tenantResolveCfg = configuration.GetSection("App:Domains"); + if (tenantResolveCfg.Exists()) + { + Configure(options => + { + var domains = tenantResolveCfg.Get(); + foreach (var domain in domains) + { + options.AddDomainTenantResolver(domain); + } + }); + } + } + + private void ConfigureAuditing(IConfiguration configuration) + { + Configure(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(); + }); + } + + private void ConfigureIdentity(IConfiguration configuration) + { + // 增加配置文件定义,在新建租户时需要 + Configure(options => + { + var identityConfiguration = configuration.GetSection("Identity"); + if (identityConfiguration.Exists()) + { + identityConfiguration.Bind(options); + } + }); + Configure(options => + { + options.IsDynamicClaimsEnabled = true; + }); + Configure(options => + { + options.IsCleanupEnabled = true; + }); + } + + private void ConfigureMvcUiTheme() + { + Configure(options => + { + //options.StyleBundles.Configure( + // LeptonXLiteThemeBundles.Styles.Global, + // bundle => + // { + // bundle.AddFiles("/global-styles.css"); + // } + //); + }); + } + + private void ConfigureLocalization() + { + Configure(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() + .AddBaseTypes( + typeof(IdentityResource), + typeof(AliyunResource), + typeof(TencentCloudResource), + typeof(WeChatResource), + typeof(PlatformResource), + typeof(AbpOpenIddictResource), + typeof(AbpIdentityServerResource)); + + options.UseAllPersistence(); + }); + + Configure(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(options => + { + options.IsEnabled = true; + // options.IsWrapUnauthorizedEnabled = true; + options.IgnoreNamespaces.Add("Elsa"); + }); + } + + private void PreConfigureWrapper() + { + //PreConfigure(options => + //{ + // options.ProxyRequestActions.Add( + // (appid, httprequestmessage) => + // { + // httprequestmessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + // }); + //}); + + PreConfigure(options => + { + options.ProxyClientActions.Add( + (_, _, client) => + { + client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); + }); + }); + } + + private void ConfigureAuditing() + { + Configure(options => + { + // options.IsEnabledForGetRequests = true; + options.ApplicationName = ApplicationName; + }); + } + + private void ConfigureUrls(IConfiguration configuration) + { + Configure(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(options => + { + options.AutoValidate = false; + }); + + services.Replace(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(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>(); + }); + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs new file mode 100644 index 000000000..ceb61611a --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs @@ -0,0 +1,394 @@ +using LINGYUN.Abp.Account; +using LINGYUN.Abp.Account.Templates; +using LINGYUN.Abp.Aliyun.SettingManagement; +using LINGYUN.Abp.AspNetCore.HttpOverrides; +using LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper; +using LINGYUN.Abp.AspNetCore.Mvc.Localization; +using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; +using LINGYUN.Abp.Auditing; +using LINGYUN.Abp.AuditLogging.EntityFrameworkCore; +using LINGYUN.Abp.Authentication.QQ; +using LINGYUN.Abp.Authentication.WeChat; +using LINGYUN.Abp.Authorization.OrganizationUnits; +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.BackgroundTasks.Activities; +using LINGYUN.Abp.BackgroundTasks.DistributedLocking; +using LINGYUN.Abp.BackgroundTasks.EventBus; +using LINGYUN.Abp.BackgroundTasks.ExceptionHandling; +using LINGYUN.Abp.BackgroundTasks.Jobs; +using LINGYUN.Abp.BackgroundTasks.Notifications; +using LINGYUN.Abp.BackgroundTasks.Quartz; +using LINGYUN.Abp.CachingManagement; +using LINGYUN.Abp.CachingManagement.StackExchangeRedis; +using LINGYUN.Abp.Dapr.Client; +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.DataProtectionManagement; +using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore; +// using LINGYUN.Abp.Demo; +// using LINGYUN.Abp.Demo.EntityFrameworkCore; +using LINGYUN.Abp.ExceptionHandling; +using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.Exporter.MiniExcel; +using LINGYUN.Abp.FeatureManagement; +using LINGYUN.Abp.FeatureManagement.HttpApi; +using LINGYUN.Abp.Features.LimitValidation; +using LINGYUN.Abp.Features.LimitValidation.Redis.Client; +using LINGYUN.Abp.Http.Client.Wrapper; +using LINGYUN.Abp.Identity; +using LINGYUN.Abp.Identity.AspNetCore.Session; +using LINGYUN.Abp.Identity.EntityFrameworkCore; +using LINGYUN.Abp.Identity.Notifications; +using LINGYUN.Abp.Identity.OrganizaztionUnits; +using LINGYUN.Abp.Identity.Session.AspNetCore; +using LINGYUN.Abp.Identity.WeChat; +using LINGYUN.Abp.IdGenerator; +using LINGYUN.Abp.IM.SignalR; +using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.Localization.Persistence; +using LINGYUN.Abp.LocalizationManagement; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MessageService; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using LINGYUN.Abp.MultiTenancy.Editions; +using LINGYUN.Abp.Notifications; +using LINGYUN.Abp.Notifications.Common; +using LINGYUN.Abp.Notifications.Emailing; +using LINGYUN.Abp.Notifications.EntityFrameworkCore; +using LINGYUN.Abp.Notifications.SignalR; +using LINGYUN.Abp.Notifications.WeChat.MiniProgram; +using LINGYUN.Abp.OpenApi.Authorization; +using LINGYUN.Abp.OpenIddict; +using LINGYUN.Abp.OpenIddict.AspNetCore; +using LINGYUN.Abp.OpenIddict.AspNetCore.Session; +using LINGYUN.Abp.OpenIddict.Portal; +using LINGYUN.Abp.OpenIddict.Sms; +using LINGYUN.Abp.OpenIddict.WeChat; +using LINGYUN.Abp.OpenIddict.WeChat.Work; +using LINGYUN.Abp.OssManagement; +using LINGYUN.Abp.OssManagement.FileSystem; +// using LINGYUN.Abp.OssManagement.Imaging; +using LINGYUN.Abp.OssManagement.SettingManagement; +using LINGYUN.Abp.PermissionManagement; +using LINGYUN.Abp.PermissionManagement.HttpApi; +using LINGYUN.Abp.PermissionManagement.OrganizationUnits; +using LINGYUN.Abp.Saas; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.Serilog.Enrichers.Application; +using LINGYUN.Abp.Serilog.Enrichers.UniqueId; +using LINGYUN.Abp.SettingManagement; +using LINGYUN.Abp.Sms.Aliyun; +using LINGYUN.Abp.TaskManagement; +using LINGYUN.Abp.TaskManagement.EntityFrameworkCore; +using LINGYUN.Abp.Tencent.QQ; +using LINGYUN.Abp.Tencent.SettingManagement; +using LINGYUN.Abp.TextTemplating; +using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; +using LINGYUN.Abp.UI.Navigation; +using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; +using LINGYUN.Abp.Webhooks; +using LINGYUN.Abp.Webhooks.EventBus; +using LINGYUN.Abp.Webhooks.Identity; +using LINGYUN.Abp.Webhooks.Saas; +using LINGYUN.Abp.WebhooksManagement; +using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; +using LINGYUN.Abp.WeChat.MiniProgram; +using LINGYUN.Abp.WeChat.Official; +using LINGYUN.Abp.WeChat.Official.Handlers; +using LINGYUN.Abp.WeChat.SettingManagement; +using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.WeChat.Work.Handlers; +using LINGYUN.Platform; +using LINGYUN.Platform.EntityFrameworkCore; +using LINGYUN.Platform.HttpApi; +using LINGYUN.Platform.Settings.VueVbenAdmin; +using LINGYUN.Platform.Theme.VueVbenAdmin; +using Volo.Abp; +using Volo.Abp.Account.Web; +using Volo.Abp.AspNetCore.Authentication.JwtBearer; +using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore.PostgreSql; +using Volo.Abp.EventBus; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Imaging; +using Volo.Abp.Modularity; +using Volo.Abp.OpenIddict.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.Identity; +using Volo.Abp.PermissionManagement.OpenIddict; +using Volo.Abp.SettingManagement; +using Volo.Abp.SettingManagement.EntityFrameworkCore; +using Volo.Abp.Threading; +// using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql; +using Volo.Abp.EntityFrameworkCore.MySQL; + +namespace PackageName.CompanyName.ProjectName.AIO.Host; + +[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().SeedAsync(); ; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs new file mode 100644 index 000000000..42108b0eb --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Microsoft/Extensions/DependencyInjection/SameSiteCookiesServiceCollectionExtensions.cs @@ -0,0 +1,67 @@ +namespace PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection +{ + public static class SameSiteCookiesServiceCollectionExtensions + { + public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services) + { + services.Configure(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; + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs new file mode 100644 index 000000000..daabe255d --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/ITenantConfigurationCache.cs @@ -0,0 +1,10 @@ +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; + +public interface ITenantConfigurationCache +{ + Task RefreshAsync(); + + Task> GetTenantsAsync(); +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs new file mode 100644 index 000000000..61f939f97 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCache.cs @@ -0,0 +1,59 @@ +using LINGYUN.Abp.Saas.Tenants; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; + +public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency +{ + protected ITenantRepository TenantRepository { get; } + protected IDistributedCache TenantCache { get; } + + public TenantConfigurationCache( + ITenantRepository tenantRepository, + IDistributedCache tenantCache) + { + TenantRepository = tenantRepository; + TenantCache = tenantCache; + } + + public async virtual Task RefreshAsync() + { + var cacheKey = GetCacheKey(); + + await TenantCache.RemoveAsync(cacheKey); + } + + public async virtual Task> GetTenantsAsync() + { + return (await GetForCacheItemAsync()).Tenants; + } + + protected async virtual Task 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"; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs new file mode 100644 index 000000000..ac10549e5 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MultiTenancy/TenantConfigurationCacheItem.cs @@ -0,0 +1,19 @@ +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.MultiTenancy; + +[IgnoreMultiTenancy] +public class TenantConfigurationCacheItem +{ + public List Tenants { get; set; } + + public TenantConfigurationCacheItem() + { + Tenants = new List(); + } + + public TenantConfigurationCacheItem(List tenants) + { + Tenants = tenants; + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj new file mode 100644 index 000000000..136d24605 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj @@ -0,0 +1,276 @@ + + + net8.0 + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml new file mode 100644 index 000000000..aed9202eb --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml @@ -0,0 +1,103 @@ +@using Volo.Abp.Account.Localization +@using Volo.Abp.Users +@using Microsoft.AspNetCore.Mvc.Localization +@using Microsoft.Extensions.Localization +@using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo +@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using Volo.Abp.Data +@using Volo.Abp.Identity.Settings +@using Volo.Abp.Localization +@using Volo.Abp.Settings +@using Volo.Abp.ObjectExtending +@inject IHtmlLocalizer 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); +} + +

@L["PersonalSettings"]


+
+ + + + + + + + + + + + + + + + + + + + @if (CurrentUser.EmailVerified) + { + + } + else + { + @**@ + @L["Validation"].Value + } + + + + + + @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + { + 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); + } + + + } + else + { + + } + } + } + + + diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js new file mode 100644 index 000000000..55a88e52e --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.js @@ -0,0 +1,28 @@ +(function ($) { + $(function () { + var l = abp.localization.getResource("AbpAccount"); + + $('#PersonalSettingsForm').submit(function (e) { + e.preventDefault(); + + if (!$('#PersonalSettingsForm').valid()) { + return false; + } + + var input = $('#PersonalSettingsForm').serializeFormToObject(); + + volo.abp.account.profile.update(input).then(function (result) { + abp.notify.success(l('PersonalSettingsSaved')); + updateConcurrencyStamp(); + }); + }); + }); + + abp.event.on('passwordChanged', updateConcurrencyStamp); + + function updateConcurrencyStamp(){ + volo.abp.account.profile.get().then(function(profile){ + $("#ConcurrencyStamp").val(profile.concurrencyStamp); + }); + } +})(jQuery); diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml new file mode 100644 index 000000000..d4d8cda0f --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml @@ -0,0 +1,17 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.EmailConfirmModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +
+
+

@L["EmailConfirm"]

+
+ + + @L["Cancel"] + + +
+
diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs new file mode 100644 index 000000000..b2ed2b28e --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirm.cshtml.cs @@ -0,0 +1,72 @@ +using LINGYUN.Abp.Account; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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 + }); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml new file mode 100644 index 000000000..8ffc6586b --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml @@ -0,0 +1,13 @@ +@page +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.EmailConfirmConfirmationModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@inject IHtmlLocalizer L +
+
+

@L["EmailConfirm"]

+

@L["YourEmailIsSuccessfullyConfirm"]

+ @L["GoToTheApplication"] +
+
diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs new file mode 100644 index 000000000..01f1f0f01 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/EmailConfirmConfirmation.cshtml.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Account.Web.Pages.Account; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 OnGetAsync() + { + ReturnUrl = await GetRedirectUrlAsync(ReturnUrl, ReturnUrlHash); + + return Page(); + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml new file mode 100644 index 000000000..8d55fdd34 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml @@ -0,0 +1,26 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.SendCodeModel +@inject IHtmlLocalizer L + +
+
+

@L["TwoFactor"]

+
+ + + +
+ +
+
+ @L["SendVerifyCode"] +
+ + @L["Login"] + + +
+
+ diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs new file mode 100644 index 000000000..8155e20f1 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendCode.cshtml.cs @@ -0,0 +1,125 @@ +using LINGYUN.Abp.Account.Emailing; +using LINGYUN.Abp.Identity.Settings; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Volo.Abp; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Sms; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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 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 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; } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml new file mode 100644 index 000000000..8f0dd7030 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml @@ -0,0 +1,16 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.SendEmailConfirmModel +@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout +
+
+

@L["EmailConfirm"]

+
+ + @L["Cancel"] + + +
+
diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs new file mode 100644 index 000000000..9d14d5710 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/SendEmailConfirm.cshtml.cs @@ -0,0 +1,73 @@ +using LINGYUN.Abp.Account; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.Identity; +using Volo.Abp.Validation; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 OnGetAsync() + { + Email = CurrentUser.Email; + + return Task.FromResult(Page()); + } + + public async virtual Task 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 + }); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs new file mode 100644 index 000000000..166f827e9 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/TwoFactorSupportedLoginModel.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.Account.Web; +using Volo.Abp.Account.Web.Pages.Account; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; +using Volo.Abp.OpenIddict; +using IdentityOptions = Microsoft.AspNetCore.Identity.IdentityOptions; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account +{ + /// + /// 重写登录模型,实现双因素登录 + /// + [Dependency(ReplaceServices = true)] + [ExposeServices(typeof(LoginModel), typeof(OpenIddictSupportedLoginModel))] + public class TwoFactorSupportedLoginModel : OpenIddictSupportedLoginModel + { + public TwoFactorSupportedLoginModel( + IAuthenticationSchemeProvider schemeProvider, + IOptions accountOptions, + IOptions identityOptions, + IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache, + AbpOpenIddictRequestHelper openIddictRequestHelper) + : base(schemeProvider, accountOptions, identityOptions, identityDynamicClaimsPrincipalContributorCache, openIddictRequestHelper) + { + + } + + protected async override Task> 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 TwoFactorLoginResultAsync() + { + // 重定向双因素认证页面 + return Task.FromResult(RedirectToPage("SendCode", new + { + returnUrl = ReturnUrl, + returnUrlHash = ReturnUrlHash, + rememberMe = LoginInput.RememberMe + })); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml new file mode 100644 index 000000000..1936197c0 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml @@ -0,0 +1,4 @@ +@page +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.UseRecoveryCodeModel +@{ +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs new file mode 100644 index 000000000..c8ccca339 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/UseRecoveryCode.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account +{ + public class UseRecoveryCodeModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml new file mode 100644 index 000000000..2b14e2168 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml @@ -0,0 +1,26 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.VerifyAuthenticatorCodeModel +@inject IHtmlLocalizer L +
+
+
+ + +
+ + + +
+
+ + +
+ @L["VerifyAuthenticatorCode"] + + @L["Login"] + +
+
+
\ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs new file mode 100644 index 000000000..899e3df30 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyAuthenticatorCode.cshtml.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Web.Pages.Account; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.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 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; } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml new file mode 100644 index 000000000..44d45b36e --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml @@ -0,0 +1,29 @@ +@page +@inject IHtmlLocalizer L +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Account.Localization +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account.VerifyCodeModel +
+
+
+ + + + +
+ +
+ + + + + +
+ @L["VerifyAuthenticatorCode"] +
+ + @L["ReSendVerifyCode"] + +
+
+
diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs new file mode 100644 index 000000000..169c48eda --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Account/VerifyCode.cshtml.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Account.Localization; +using Volo.Abp.Account.Web.Pages.Account; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages.Account +{ + public class VerifyCodeModel : AccountPageModel + { + [BindProperty] + public VerifyCodeInputModel Input { get; set; } + /// + /// ˫������֤�ṩ���� + /// + [HiddenInput] + [BindProperty(SupportsGet = true)] + public string Provider { get; set; } + /// + /// �ض���Url + /// + [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 VerifyCodeModel() + { + LocalizationResourceType = typeof(AccountResource); + } + + public virtual IActionResult OnGet() + { + Input = new VerifyCodeInputModel(); + + return Page(); + } + + public virtual async Task 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 + { + /// + /// �Ƿ���������м�ס��¼״̬ + /// + public bool RememberBrowser { get; set; } + /// + /// ���͵���֤�� + /// + [Required] + public string VerifyCode { get; set; } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml new file mode 100644 index 000000000..c149bd95d --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml @@ -0,0 +1,36 @@ +@page +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Alert +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid +@using Volo.Abp.Users +@model PackageName.CompanyName.ProjectName.AIO.Host.Pages.IndexModel +@inject ICurrentUser CurrentUser +@if (CurrentUser.IsAuthenticated) +{ +
+ + + + Logout + + +

@CurrentUser.UserName

+
@CurrentUser.Email
+
+ Roles: @CurrentUser.Roles.JoinAsString(", ") +
+ Claims:
+ @Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString("
")) +
+
+
+
+} + +@if (!CurrentUser.IsAuthenticated) +{ +
+

+ Login +
+} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs new file mode 100644 index 000000000..7047bc406 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/Index.cshtml.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.Pages +{ + public class IndexModel : AbpPageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml new file mode 100644 index 000000000..c1da1f5f1 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs new file mode 100644 index 000000000..3daf07fe4 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Program.cs @@ -0,0 +1,82 @@ +using LINGYUN.Abp.Identity.Session.AspNetCore; +using PackageName.CompanyName.ProjectName.AIO.Host; +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(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(); diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json new file mode 100644 index 000000000..337677308 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:19139", + "sslPort": 0 + } + }, + "profiles": { + "LY.MicroService.Applications.Single": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://0.0.0.0:30001", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Production" + } + }, + "LY.MicroService.Applications.Single.Development": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://0.0.0.0:30000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs new file mode 100644 index 000000000..a4218a9c4 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/TenantHeaderParamter.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using Volo.Abp.AspNetCore.MultiTenancy; +using Volo.Abp.MultiTenancy; + +namespace PackageName.CompanyName.ProjectName.AIO.Host; + +public class TenantHeaderParamter : IOperationFilter +{ + private readonly AbpMultiTenancyOptions _multiTenancyOptions; + private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions; + public TenantHeaderParamter( + IOptions multiTenancyOptions, + IOptions aspNetCoreMultiTenancyOptions) + { + _multiTenancyOptions = multiTenancyOptions.Value; + _aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value; + } + + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (_multiTenancyOptions.IsEnabled) + { + operation.Parameters = operation.Parameters ?? new List(); + operation.Parameters.Add(new OpenApiParameter + { + Name = _aspNetCoreMultiTenancyOptions.TenantKey, + In = ParameterLocation.Header, + Description = "Tenant Id in http header", + Required = false + }); + } + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs new file mode 100644 index 000000000..31aafda51 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/TextMessageReplyContributor.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Official.Messages.Models; +using LINGYUN.Abp.WeChat.Official.Services; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; +/// +/// 文本消息客服回复 +/// +public class TextMessageReplyContributor : IMessageHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + 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))); + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs new file mode 100644 index 000000000..806302c0d --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Official/Messages/UserSubscribeEventContributor.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Official.Messages.Models; +using LINGYUN.Abp.WeChat.Official.Services; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Official.Messages; +/// +/// 用户关注回复消息 +/// +public class UserSubscribeEventContributor : IEventHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + await messageSender.SendAsync( + new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel( + context.Message.FromUserName, + new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage( + "感谢您的关注, 点击菜单了解更多."))); + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs new file mode 100644 index 000000000..f85f858a1 --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/WeChat/Work/Messages/TextMessageReplyContributor.cs @@ -0,0 +1,24 @@ +using LINGYUN.Abp.WeChat.Common.Messages.Handlers; +using LINGYUN.Abp.WeChat.Work.Common.Messages.Models; +using LINGYUN.Abp.WeChat.Work.Messages; + +namespace PackageName.CompanyName.ProjectName.AIO.Host.WeChat.Work.Messages; +/// +/// 文本消息客服回复 +/// +public class TextMessageReplyContributor : IMessageHandleContributor +{ + public async virtual Task HandleAsync(MessageHandleContext context) + { + var messageSender = context.ServiceProvider.GetRequiredService(); + + 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, + }); + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json new file mode 100644 index 000000000..4f753c08e --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json @@ -0,0 +1,249 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//Mysql +// "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;"//Postgres + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "Console": true, + "Http": true, + "Email": true, + "TemporalQuartz": true, + "JavaScriptActivities": true, + "UserTask": true, + "Conductor": true, + "Telnyx": true, + "BlobStoring": true, + "Emailing": true, + "Notification": true, + "Sms": true, + "IM": true, + "PublishWebhook": true, + "Webhooks": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + } + }, + "Server": { + "BaseUrl": "http://127.0.0.1:30000" + } + }, + "Quartz": { + "UsePersistentStore": false, + "Properties": { + "quartz.jobStore.dataSource": "tkm", + "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz", + "quartz.dataSource.tkm.connectionStringName": "Default", + "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz", + "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456", + "quartz.dataSource.tkm.provider": "MySqlConnector", +// "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", +// "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;", +// "quartz.dataSource.tkm.provider": "Npgsql", + "quartz.jobStore.clustered": "true", + "quartz.serializer.type": "json" + } + }, + "Redis": { + "IsEnabled": true, + "Configuration": "127.0.0.1,defaultDatabase=15", + "InstanceName": "LINGYUN.Abp.Application" + }, + "Features": { + "Validation": { + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=13", + "InstanceName": "LINGYUN.Abp.Application" + } + } + }, + "AuthServer": { + "UseOpenIddict": true, + "Authority": "http://127.0.0.1:30001/", + "Audience": "lingyun-abp-application", + "RequireHttpsMetadata": false, + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "IdentityServer": { + "Clients": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + }, + "Lifetime": { + "AuthorizationCode": "00:05:00", + "AccessToken": "14:00:00", + "DeviceCode": "00:10:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00", + "RefreshTokenReuseLeeway": "00:00:30", + "UserCode": "00:10:00" + } + }, + "Identity": { + "Password": { + "RequiredLength": 6, + "RequiredUniqueChars": 0, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + }, + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + }, + "TextTemplating": { + "IsDynamicStoreEnabled": true + }, + "WebhooksManagement": { + "IsDynamicStoreEnabled": true + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "abp.dev.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + }, + "Minio": { + "WithSSL": false, + "BucketName": "blobs", + "EndPoint": "127.0.0.1:19000", + "AccessKey": "ZD43kNpimiJf9mCuomTP", + "SecretKey": "w8IqMgi4Tnz0DGzN8jZ7IJWq7OEdbUnAU0jlZxQK", + "CreateBucketIfNotExists": false + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://127.0.0.1:9200", + "indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json new file mode 100644 index 000000000..ff9beea3e --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.json @@ -0,0 +1,89 @@ +{ + "Clock": { + "Kind": "Local" + }, + "Forwarded": { + "ForwardedHeaders": "XForwardedFor,XForwardedProto" + }, + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "Json": { + "OutputDateTimeFormat": "yyyy-MM-dd HH:mm:ss", + "InputDateTimeFormats": [ + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-ddTHH:mm:ss" + ] + }, + "AllowedHosts": "*", + "Hosting": { + "BasePath": "" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Information" + } + }, + "Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Debug-.log", + "restrictedToMinimumLevel": "Debug", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Info-.log", + "restrictedToMinimumLevel": "Information", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Warn-.log", + "restrictedToMinimumLevel": "Warning", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Error-.log", + "restrictedToMinimumLevel": "Error", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "Logs/Fatal-.log", + "restrictedToMinimumLevel": "Fatal", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + } + ] + } +} diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js new file mode 100644 index 000000000..bec4d578f --- /dev/null +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/gulpfile.js @@ -0,0 +1,10 @@ +"use strict"; + +var gulp = require("gulp"), + path = require('path'), + copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js'); + +exports.default = function(done){ + copyResources(path.resolve('./')); + done(); +}; \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj new file mode 100644 index 000000000..3fe9a4c81 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj @@ -0,0 +1,54 @@ + + + Exe + net8.0 + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + PreserveNewest + true + PreserveNewest + + + + PreserveNewest + + + + PreserveNewest + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs new file mode 100644 index 000000000..7153c46d4 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs @@ -0,0 +1,44 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; + +namespace PackageName.CompanyName.ProjectName.AIO.DbMigrator; + +public class Program +{ + public async static Task Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) +#if DEBUG + .MinimumLevel.Override("LY.MicroService.Applications.Single.DbMigrator", LogEventLevel.Debug) +#else + .MinimumLevel.Override("LY.MicroService.Applications.Single.DbMigrator", LogEventLevel.Information) +#endif + .Enrich.FromLogContext() + .WriteTo.Console() + .WriteTo.File("Logs/migrations.txt") + .CreateLogger(); + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + // .ConfigureAppConfiguration((context, builder) => + // { + // builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + // .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true); + // } ) + .ConfigureLogging((context, logging) => logging.ClearProviders()) + .ConfigureServices((hostContext, services) => + { + services.AddHostedService(); + }); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md new file mode 100644 index 000000000..e60db3ab6 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md @@ -0,0 +1,75 @@ +# LY.MicroService.Applications.Single.DbMigrator + +Single application database migration tool for automatically executing database migrations and initializing data. + +[简体中文](./README.md) + +## Features + +* Automatic database migration execution +* Multi-environment configuration support +* Integrated Serilog logging +* Data migration environment configuration support +* Automatic database migration check and application +* Console application, easy to integrate into CI/CD pipelines + +## Configuration + +```json +{ + "ConnectionStrings": { + "Default": "your-database-connection-string" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Volo.Abp": "Warning" + } + } + } +} +``` + +## Basic Usage + +1. Configure Database Connection + * Configure database connection string in appsettings.json + * Use appsettings.{Environment}.json for different environment configurations + +2. Run Migration Tool + ```bash + dotnet run + ``` + +3. View Migration Logs + * Console output + * Logs/migrations.txt file + +## Environment Variables + +* `ASPNETCORE_ENVIRONMENT`: Set runtime environment (Development, Staging, Production, etc.) +* `DOTNET_ENVIRONMENT`: Same as above, for compatibility + +## Notes + +* Ensure database connection string includes sufficient permissions +* Recommended to backup database before executing migrations +* Check migrations.txt log file for migration details +* If migration fails, check error messages in logs + +## Development and Debugging + +1. Set Environment Variables + ```bash + export ASPNETCORE_ENVIRONMENT=Development + ``` + +2. Debug with Visual Studio or Visual Studio Code + * Set breakpoints + * View detailed migration process + +3. Customize Migration Logic + * Modify SingleDbMigrationService class + * Add new data seeds diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md new file mode 100644 index 000000000..1a997f51b --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md @@ -0,0 +1,75 @@ +# LY.MicroService.Applications.Single.DbMigrator + +单体应用数据库迁移工具,用于自动执行数据库迁移和初始化数据。 + +[English](./README.EN.md) + +## 功能特性 + +* 自动执行数据库迁移 +* 支持多环境配置 +* 集成Serilog日志记录 +* 支持数据迁移环境配置 +* 自动检查和应用数据库迁移 +* 控制台应用程序,方便集成到CI/CD流程 + +## 配置项 + +```json +{ + "ConnectionStrings": { + "Default": "你的数据库连接字符串" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Volo.Abp": "Warning" + } + } + } +} +``` + +## 基本用法 + +1. 配置数据库连接 + * 在appsettings.json中配置数据库连接字符串 + * 可以通过appsettings.{Environment}.json配置不同环境的连接字符串 + +2. 运行迁移工具 + ```bash + dotnet run + ``` + +3. 查看迁移日志 + * 控制台输出 + * Logs/migrations.txt文件 + +## 环境变量 + +* `ASPNETCORE_ENVIRONMENT`: 设置运行环境(Development、Staging、Production等) +* `DOTNET_ENVIRONMENT`: 同上,用于兼容性 + +## 注意事项 + +* 确保数据库连接字符串中包含足够的权限 +* 建议在执行迁移前备份数据库 +* 查看migrations.txt日志文件以了解迁移详情 +* 如果迁移失败,检查日志中的错误信息 + +## 开发调试 + +1. 设置环境变量 + ```bash + export ASPNETCORE_ENVIRONMENT=Development + ``` + +2. 使用Visual Studio或Visual Studio Code进行调试 + * 可以设置断点 + * 查看详细的迁移过程 + +3. 自定义迁移逻辑 + * 修改SingleDbMigrationService类 + * 添加新的数据种子 diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs new file mode 100644 index 000000000..2c15b65f1 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs @@ -0,0 +1,51 @@ +using LY.MicroService.Applications.Single.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using Volo.Abp; +using Volo.Abp.Data; + +namespace PackageName.CompanyName.ProjectName.AIO.DbMigrator; + +public class SingleDbMigratorHostedService : IHostedService +{ + private readonly IHostApplicationLifetime _hostApplicationLifetime; + private readonly IConfiguration _configuration; + + public SingleDbMigratorHostedService( + IHostApplicationLifetime hostApplicationLifetime, + IConfiguration configuration) + { + _hostApplicationLifetime = hostApplicationLifetime; + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using var application = await AbpApplicationFactory + .CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + options.Services.AddLogging(c => c.AddSerilog()); + options.AddDataMigrationEnvironment(); + }); + await application.InitializeAsync(); + + await application + .ServiceProvider + .GetRequiredService() + .CheckAndApplyDatabaseMigrationsAsync(); + + await application.ShutdownAsync(); + + _hostApplicationLifetime.StopApplication(); + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs new file mode 100644 index 000000000..0c4baaacb --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Configuration; +using Volo.Abp.Timing; + +namespace PackageName.CompanyName.ProjectName.AIO.DbMigrator; +public partial class SingleDbMigratorModule +{ + private void ConfigureTiming(IConfiguration configuration) + { + Configure(options => + { + configuration.GetSection("Clock").Bind(options); + }); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs new file mode 100644 index 000000000..f730fe211 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; +using Microsoft.Extensions.DependencyInjection; +using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName.AIO.DbMigrator; + +[DependsOn( + typeof(AbpUINavigationVueVbenAdminModule), + // typeof(SingleMigrationsEntityFrameworkCorePostgreSqlModule), + typeof(SingleMigrationsEntityFrameworkCoreMySqlModule), + typeof(AbpAutofacModule) + )] +public partial class SingleDbMigratorModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + ConfigureTiming(configuration); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Usings.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Usings.cs new file mode 100644 index 000000000..c79c834ca --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Usings.cs @@ -0,0 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using LINGYUN.Abp; diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json new file mode 100644 index 000000000..d6bbaf791 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json @@ -0,0 +1,228 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Workflow", + "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": "Workflow", + "EntityFrameworkCore": { + "MySql": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Workflow", + "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.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.connectionStringName": "TaskManagement", + "quartz.dataSource.tkm.provider": "MySqlConnector", + "quartz.jobStore.clustered": "true", + "quartz.serializer.type": "json" + } + }, + "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" + } + } + ] + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json new file mode 100644 index 000000000..6858f5041 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json @@ -0,0 +1,228 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { + "Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "PostgreSql": { + "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": { + "PostgreSql": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "PostgreSql": { + "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.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", + "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" + } + } + ] + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json new file mode 100644 index 000000000..555dab9fb --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json @@ -0,0 +1,228 @@ +{ + "App": { + "ShowPii": true, + "SelfUrl": "http://127.0.0.1:30001/", + "CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", + "Urls": { + "Applications": { + "MVC": { + "RootUrl": "http://127.0.0.1:30001/", + "Urls": { + "Abp.Account.EmailConfirm": "Account/EmailConfirm", + "Abp.Account.EmailVerifyLogin": "Account/VerifyCode" + } + }, + "STS": { + "RootUrl": "http://127.0.0.1:30001/" + }, + "VueVbenAdmin": { + "RootUrl": "http://127.0.0.1:3100", + "Urls": { + "Abp.Account.EmailConfirm": "account/email-confirm" + } + } + } + } + }, + "Auditing": { + "AllEntitiesSelector": true + }, + "DistributedCache": { + "HideErrors": true, + "KeyPrefix": "LINGYUN.Abp.Application", + "GlobalCacheEntryOptions": { + "SlidingExpiration": "30:00:00", + "AbsoluteExpirationRelativeToNow": "60:00:00" + } + }, + "ConnectionStrings": { + "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=True" + }, + "DistributedLock": { + "IsEnabled": true, + "Redis": { + "Configuration": "127.0.0.1,defaultDatabase=14" + } + }, + "Elsa": { + "Features": { + "DefaultPersistence": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "SqlServer": { + "Enabled": true + } + } + }, + "Console": true, + "Http": true, + "Email": true, + "TemporalQuartz": true, + "JavaScriptActivities": true, + "UserTask": true, + "Conductor": true, + "Telnyx": true, + "BlobStoring": true, + "Emailing": true, + "Notification": true, + "Sms": true, + "IM": true, + "PublishWebhook": true, + "Webhooks": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "SqlServer": { + "Enabled": true + } + } + }, + "WorkflowSettings": { + "Enabled": true, + "ConnectionStringIdentifier": "Default", + "EntityFrameworkCore": { + "SqlServer": { + "Enabled": true + } + } + } + }, + "Server": { + "BaseUrl": "http://127.0.0.1:30000" + } + }, + "Quartz": { + "UsePersistentStore": false, + "Properties": { + "quartz.jobStore.dataSource": "tkm", + "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", + "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz", + "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=sa;Password=yourStrong(!)Password;", + "quartz.dataSource.tkm.provider": "SqlServer", + "quartz.jobStore.clustered": "true", + "quartz.serializer.type": "json", + "quartz.dataSource.tkm.connectionStringName": "TaskManagement" + } + }, + "Redis": { + "IsEnabled": true, + "Configuration": "127.0.0.1,defaultDatabase=15", + "InstanceName": "LINGYUN.Abp.Application" + }, + "AuthServer": { + "UseOpenIddict": true, + "Authority": "http://127.0.0.1:30001/", + "ApiName": "lingyun-abp-application", + "SwaggerClientId": "InternalServiceClient", + "SwaggerClientSecret": "1q2w3E*" + }, + "IdentityServer": { + "Clients": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:3100/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + }, + "Lifetime": { + "AuthorizationCode": "00:05:00", + "AccessToken": "14:00:00", + "DeviceCode": "00:10:00", + "IdentityToken": "00:20:00", + "RefreshToken": "14:00:00", + "RefreshTokenReuseLeeway": "00:00:30", + "UserCode": "00:10:00" + } + }, + "Identity": { + "Password": { + "RequiredLength": 6, + "RequiredUniqueChars": 0, + "RequireNonAlphanumeric": false, + "RequireLowercase": false, + "RequireUppercase": false, + "RequireDigit": false + }, + "Lockout": { + "AllowedForNewUsers": false, + "LockoutDuration": 5, + "MaxFailedAccessAttempts": 5 + }, + "SignIn": { + "RequireConfirmedEmail": false, + "RequireConfirmedPhoneNumber": false + } + }, + "FeatureManagement": { + "IsDynamicStoreEnabled": true + }, + "SettingManagement": { + "IsDynamicStoreEnabled": true + }, + "PermissionManagement": { + "IsDynamicStoreEnabled": true + }, + "TextTemplating": { + "IsDynamicStoreEnabled": true + }, + "WebhooksManagement": { + "IsDynamicStoreEnabled": true + }, + "Logging": { + "Serilog": { + "Elasticsearch": { + "IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" + } + } + }, + "AuditLogging": { + "Elasticsearch": { + "IndexPrefix": "abp.dev.auditing" + } + }, + "Elasticsearch": { + "NodeUris": "http://127.0.0.1:9200" + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "DotNetCore": "Debug" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "restrictedToMinimumLevel": "Debug", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Elasticsearch", + "Args": { + "nodeUris": "http://127.0.0.1:9200", + "indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", + "autoRegisterTemplate": true, + "autoRegisterTemplateVersion": "ESv7" + } + } + ] + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json new file mode 100644 index 000000000..4a3dae71a --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json @@ -0,0 +1,104 @@ +{ + "Clock": { + "Kind": "Local" + }, + "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;SslMode=Prefer"//PostgreSql + }, + "StringEncryption": { + "DefaultPassPhrase": "s46c5q55nxpeS8Ra", + "InitVectorBytes": "s83ng0abvd02js84", + "DefaultSalt": "sf&5)s3#" + }, + "AuthServer": { + "UseOpenIddict": true + }, + "IdentityServer": { + "Clients": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:40080/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "OpenIddict": { + "Applications": { + "VueAdmin": { + "ClientId": "vue-admin-client", + "RootUrl": "http://127.0.0.1:40080/" + }, + "InternalService": { + "ClientId": "InternalServiceClient" + } + } + }, + "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}" + } + } + ] + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml new file mode 100644 index 000000000..be68c182b --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj new file mode 100644 index 000000000..5af36315b --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj @@ -0,0 +1,22 @@ + + + + + + + net8.0 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md new file mode 100644 index 000000000..e1e97c34f --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md @@ -0,0 +1,59 @@ +# MySQL Database Migration Guide + +This guide will help you manage MySQL 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 MySQL 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 MySQL database context from the menu: + ``` + [1] LY.MicroService.Applications.Single.EntityFrameworkCore.MySql + ``` + +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.MySql/ +``` + +### 3. Apply Migration + +Generated SQL scripts can be applied to database through: + +1. Using MySQL client tools to execute SQL script directly +2. Or using command line: + ```powershell + mysql -u your_username -p your_database < your_script.sql + ``` diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md new file mode 100644 index 000000000..295e1e512 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md @@ -0,0 +1,59 @@ +# MySQL 数据库迁移指南 + +本指南将帮助您使用迁移脚本来管理 MySQL 数据库的迁移操作。 + +## 前置条件 + +1. 确保已安装 .NET Core SDK +2. 确保已安装 Entity Framework Core 工具 + ```powershell + dotnet tool install --global dotnet-ef + ``` +3. 确保已正确配置 MySQL 连接字符串 + +## 使用说明 + +### 1. 创建新的迁移 + +1. 在 `aspnet-core/migrations` 目录下运行迁移脚本: + ```powershell + # 使用中文版本 + .\Migrate.ps1 + + # 或使用英文版本 + .\MigrateEn.ps1 + ``` + +2. 在菜单中选择 MySQL 数据库上下文: + ``` + [1] LY.MicroService.Applications.Single.EntityFrameworkCore.MySql + ``` + +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.MySql/ +``` + +### 3. 应用迁移 + +生成的 SQL 脚本可以通过以下方式应用到数据库: + +1. 使用 MySQL 客户端工具直接执行 SQL 脚本 +2. 或使用命令行: + ```powershell + mysql -u your_username -p your_database < your_script.sql + ``` diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs new file mode 100644 index 000000000..d34ba6dd0 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs @@ -0,0 +1,32 @@ +using LY.MicroService.Applications.Single.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using System.IO; + +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql; + +public class SingleMigrationsDbContextFactory : IDesignTimeDbContextFactory +{ + public SingleMigrationsDbContext CreateDbContext(string[] args) + { + var configuration = BuildConfiguration(); + var connectionString = configuration.GetConnectionString("Default"); + + var builder = new DbContextOptionsBuilder() + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), b => b.MigrationsAssembly("LY.MicroService.Applications.Single.EntityFrameworkCore.MySql")); + + 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.MySql.json", optional: true); + + return builder.Build(); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs new file mode 100644 index 000000000..e15058880 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs @@ -0,0 +1,24 @@ +using LY.MicroService.Applications.Single.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.MySQL; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql; + +[DependsOn( + typeof(AbpEntityFrameworkCoreMySQLModule), + typeof(SingleMigrationsEntityFrameworkCoreModule) + )] +public class SingleMigrationsEntityFrameworkCoreMySqlModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAbpDbContext(); + + Configure(options => + { + options.UseMySQL(); + }); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs new file mode 100644 index 000000000..d3cfdd062 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs @@ -0,0 +1,469 @@ +using LINGYUN.Abp.IdentityServer.IdentityResources; +using Microsoft.Extensions.Configuration; +using OpenIddict.Abstractions; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.IdentityServer.ApiResources; +using Volo.Abp.IdentityServer.ApiScopes; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.IdentityServer.IdentityResources; +using Volo.Abp.MultiTenancy; +using Volo.Abp.PermissionManagement; + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore.DataSeeder; + +public class ClientDataSeederContributor : IDataSeedContributor, ITransientDependency +{ + private readonly IOpenIddictApplicationManager _applicationManager; + private readonly IOpenIddictScopeManager _scopeManager; + + private readonly IClientRepository _clientRepository; + private readonly IApiResourceRepository _apiResourceRepository; + private readonly IApiScopeRepository _apiScopeRepository; + private readonly ICustomIdentityResourceDataSeeder _customIdentityResourceDataSeeder; + private readonly IIdentityResourceDataSeeder _identityResourceDataSeeder; + + private readonly IGuidGenerator _guidGenerator; + private readonly IPermissionDataSeeder _permissionDataSeeder; + private readonly IConfiguration _configuration; + private readonly ICurrentTenant _currentTenant; + + public ClientDataSeederContributor( + IOpenIddictApplicationManager applicationManager, + IOpenIddictScopeManager scopeManager, + IClientRepository clientRepository, + IApiResourceRepository apiResourceRepository, + IApiScopeRepository apiScopeRepository, + ICustomIdentityResourceDataSeeder customIdentityResourceDataSeeder, + IIdentityResourceDataSeeder identityResourceDataSeeder, + IGuidGenerator guidGenerator, + IPermissionDataSeeder permissionDataSeeder, + IConfiguration configuration, + ICurrentTenant currentTenant) + { + _applicationManager = applicationManager; + _scopeManager = scopeManager; + _clientRepository = clientRepository; + _apiResourceRepository = apiResourceRepository; + _apiScopeRepository = apiScopeRepository; + _customIdentityResourceDataSeeder = customIdentityResourceDataSeeder; + _identityResourceDataSeeder = identityResourceDataSeeder; + _guidGenerator = guidGenerator; + _permissionDataSeeder = permissionDataSeeder; + _configuration = configuration; + _currentTenant = currentTenant; + } + + public async virtual Task SeedAsync(DataSeedContext context) + { + using (_currentTenant.Change(context.TenantId)) + { + if (_configuration.GetValue("AuthServer:UseOpenIddict")) + { + await SeedOpenIddictAsync(); + return; + } + + await SeedIdentityServerAsync(); + } + } + + #region OpenIddict + + private async Task SeedOpenIddictAsync() + { + await CreateScopeAsync("lingyun-abp-application"); + await CreateApplicationAsync("lingyun-abp-application"); + } + + private async Task CreateScopeAsync(string scope) + { + if (await _scopeManager.FindByNameAsync(scope) == null) + { + await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor() + { + Name = scope, + DisplayName = scope + " access", + DisplayNames = + { + [CultureInfo.GetCultureInfo("zh-Hans")] = "Abp API 应用程序访问", + [CultureInfo.GetCultureInfo("en")] = "Abp API Application Access" + }, + Resources = + { + scope + } + }); + } + } + + private async Task CreateApplicationAsync(string scope) + { + var configurationSection = _configuration.GetSection("OpenIddict:Applications"); + + var vueClientId = configurationSection["VueAdmin:ClientId"]; + if (!vueClientId.IsNullOrWhiteSpace()) + { + var vueClientRootUrl = configurationSection["VueAdmin:RootUrl"].EnsureEndsWith('/'); + + if (await _applicationManager.FindByClientIdAsync(vueClientId) == null) + { + await _applicationManager.CreateAsync(new OpenIddictApplicationDescriptor + { + ClientId = vueClientId, + ClientSecret = "1q2w3e*", + ApplicationType = OpenIddictConstants.ApplicationTypes.Web, + ConsentType = OpenIddictConstants.ConsentTypes.Explicit, + DisplayName = "Abp Vue Admin Client", + PostLogoutRedirectUris = + { + new Uri(vueClientRootUrl + "signout-callback-oidc"), + new Uri(vueClientRootUrl) + }, + RedirectUris = + { + new Uri(vueClientRootUrl + "/signin-oidc"), + new Uri(vueClientRootUrl) + }, + Permissions = + { + OpenIddictConstants.Permissions.Endpoints.Authorization, + OpenIddictConstants.Permissions.Endpoints.Token, + OpenIddictConstants.Permissions.Endpoints.Device, + OpenIddictConstants.Permissions.Endpoints.Introspection, + OpenIddictConstants.Permissions.Endpoints.Revocation, + OpenIddictConstants.Permissions.Endpoints.Logout, + + OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, + OpenIddictConstants.Permissions.GrantTypes.Implicit, + OpenIddictConstants.Permissions.GrantTypes.Password, + OpenIddictConstants.Permissions.GrantTypes.RefreshToken, + OpenIddictConstants.Permissions.GrantTypes.DeviceCode, + OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, + + OpenIddictConstants.Permissions.ResponseTypes.Code, + OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken, + OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken, + OpenIddictConstants.Permissions.ResponseTypes.CodeToken, + OpenIddictConstants.Permissions.ResponseTypes.IdToken, + OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken, + OpenIddictConstants.Permissions.ResponseTypes.None, + OpenIddictConstants.Permissions.ResponseTypes.Token, + + OpenIddictConstants.Permissions.Scopes.Roles, + OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Address, + OpenIddictConstants.Permissions.Scopes.Phone, + OpenIddictConstants.Permissions.Prefixes.Scope + scope + } + }); + + var vueClientPermissions = new string[1] + { + "AbpIdentity.UserLookup" + }; + await _permissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, vueClientId, vueClientPermissions); + } + } + + var internalServiceClientId = configurationSection["InternalService:ClientId"]; + if (!internalServiceClientId.IsNullOrWhiteSpace()) + { + if (await _applicationManager.FindByClientIdAsync(internalServiceClientId) == null) + { + await _applicationManager.CreateAsync(new OpenIddictApplicationDescriptor + { + ClientId = internalServiceClientId, + ClientSecret = "1q2w3e*", + ClientType = OpenIddictConstants.ClientTypes.Confidential, + ConsentType = OpenIddictConstants.ConsentTypes.Explicit, + ApplicationType = OpenIddictConstants.ApplicationTypes.Native, + DisplayName = "Abp Vue Admin Client", + Permissions = + { + OpenIddictConstants.Permissions.Endpoints.Authorization, + OpenIddictConstants.Permissions.Endpoints.Token, + OpenIddictConstants.Permissions.Endpoints.Device, + OpenIddictConstants.Permissions.Endpoints.Introspection, + OpenIddictConstants.Permissions.Endpoints.Revocation, + OpenIddictConstants.Permissions.Endpoints.Logout, + + OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, + OpenIddictConstants.Permissions.GrantTypes.Implicit, + OpenIddictConstants.Permissions.GrantTypes.Password, + OpenIddictConstants.Permissions.GrantTypes.RefreshToken, + OpenIddictConstants.Permissions.GrantTypes.DeviceCode, + OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, + + OpenIddictConstants.Permissions.ResponseTypes.Code, + OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken, + OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken, + OpenIddictConstants.Permissions.ResponseTypes.CodeToken, + OpenIddictConstants.Permissions.ResponseTypes.IdToken, + OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken, + OpenIddictConstants.Permissions.ResponseTypes.None, + OpenIddictConstants.Permissions.ResponseTypes.Token, + + OpenIddictConstants.Permissions.Scopes.Roles, + OpenIddictConstants.Permissions.Scopes.Profile, + OpenIddictConstants.Permissions.Scopes.Email, + OpenIddictConstants.Permissions.Scopes.Address, + OpenIddictConstants.Permissions.Scopes.Phone, + OpenIddictConstants.Permissions.Prefixes.Scope + scope + } + }); + + var internalServicePermissions = new string[2] + { + "AbpIdentity.UserLookup","AbpIdentity.Users" + }; + await _permissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, internalServiceClientId, internalServicePermissions); + } + } + } + + #endregion + + #region IdentityServer + + private async Task SeedIdentityServerAsync() + { + await _identityResourceDataSeeder.CreateStandardResourcesAsync(); + await _customIdentityResourceDataSeeder.CreateCustomResourcesAsync(); + await CreateApiResourcesAsync(); + await CreateApiScopesAsync(); + await CreateClientsAsync(); + } + + private async Task CreateApiScopesAsync() + { + await CreateApiScopeAsync("lingyun-abp-application"); + } + + private async Task CreateApiResourcesAsync() + { + var commonApiUserClaims = new[] + { + "email", + "email_verified", + "name", + "phone_number", + "phone_number_verified", + "role" + }; + + await CreateApiResourceAsync("lingyun-abp-application", commonApiUserClaims); + } + + private async Task CreateApiResourceAsync(string name, IEnumerable claims, IEnumerable secrets = null) + { + var apiResource = await _apiResourceRepository.FindByNameAsync(name); + if (apiResource == null) + { + apiResource = await _apiResourceRepository.InsertAsync( + new ApiResource( + _guidGenerator.Create(), + name, + name + " API" + ), + autoSave: true + ); + } + + foreach (var claim in claims) + { + if (apiResource.FindClaim(claim) == null) + { + apiResource.AddUserClaim(claim); + } + } + if (secrets != null) + { + foreach (var secret in secrets) + { + if (apiResource.FindSecret(secret) == null) + { + apiResource.AddSecret(secret); + } + } + } + + return await _apiResourceRepository.UpdateAsync(apiResource); + } + + private async Task CreateApiScopeAsync(string name) + { + var apiScope = await _apiScopeRepository.FindByNameAsync(name); + if (apiScope == null) + { + apiScope = await _apiScopeRepository.InsertAsync( + new ApiScope( + _guidGenerator.Create(), + name, + name + " API" + ), + autoSave: true + ); + } + + return apiScope; + } + + private async Task CreateClientsAsync() + { + + string commonSecret = IdentityServer4.Models.HashExtensions.Sha256("1q2w3e*"); + + var commonScopes = new[] + { + "email", + "openid", + "profile", + "role", + "phone", + "address", + "offline_access" // 加上刷新, + + }; + + var configurationSection = _configuration.GetSection("IdentityServer:Clients"); + + var vueClientId = configurationSection["VueAdmin:ClientId"]; + if (!vueClientId.IsNullOrWhiteSpace()) + { + var vueClientPermissions = new string[1] + { + "AbpIdentity.UserLookup" + }; + var vueClientRootUrl = configurationSection["VueAdmin:RootUrl"].EnsureEndsWith('/'); + await CreateClientAsync( + vueClientId, + commonScopes.Union(new[] { "lingyun-abp-application" }), + new[] { "password", "client_credentials", "implicit", "phone_verify", "wx-mp" }, + commonSecret, + redirectUri: $"{vueClientRootUrl}signin-oidc", + postLogoutRedirectUri: $"{vueClientRootUrl}signout-callback-oidc", + corsOrigins: configurationSection["CorsOrigins"], + permissions: vueClientPermissions + ); + } + + // InternalService 内部服务间通讯客户端,必要的话需要在前端指定它拥有所有权限,当前项目仅预置用户查询权限 + var internalServiceClientId = configurationSection["InternalService:ClientId"]; + if (!internalServiceClientId.IsNullOrWhiteSpace()) + { + var internalServicePermissions = new string[2] + { + "AbpIdentity.UserLookup","AbpIdentity.Users" + }; + await CreateClientAsync( + internalServiceClientId, + commonScopes.Union(new[] { "lingyun-abp-application" }), + new[] { "client_credentials" }, + commonSecret, + permissions: internalServicePermissions + ); + } + } + + private async Task CreateClientAsync( + string name, + IEnumerable scopes, + IEnumerable grantTypes, + string secret, + string redirectUri = null, + string postLogoutRedirectUri = null, + IEnumerable permissions = null, + string corsOrigins = null) + { + var client = await _clientRepository.FindByClientIdAsync(name); + if (client == null) + { + client = await _clientRepository.InsertAsync( + new Client( + _guidGenerator.Create(), + name + ) + { + ClientName = name, + ProtocolType = "oidc", + Description = name, + AlwaysIncludeUserClaimsInIdToken = true, + AllowOfflineAccess = true, + AbsoluteRefreshTokenLifetime = 10800, //3 hours + AccessTokenLifetime = 7200, //2 hours + AuthorizationCodeLifetime = 300, + IdentityTokenLifetime = 300, + RequireConsent = false + }, + autoSave: true + ); + } + + foreach (var scope in scopes) + { + if (client.FindScope(scope) == null) + { + client.AddScope(scope); + } + } + + foreach (var grantType in grantTypes) + { + if (client.FindGrantType(grantType) == null) + { + client.AddGrantType(grantType); + } + } + + if (client.FindSecret(secret) == null) + { + client.AddSecret(secret); + } + + if (redirectUri != null) + { + if (client.FindRedirectUri(redirectUri) == null) + { + client.AddRedirectUri(redirectUri); + } + } + + if (postLogoutRedirectUri != null) + { + if (client.FindPostLogoutRedirectUri(postLogoutRedirectUri) == null) + { + client.AddPostLogoutRedirectUri(postLogoutRedirectUri); + } + } + + if (corsOrigins != null) + { + var corsOriginsSplit = corsOrigins.Split(";"); + foreach (var corsOrigin in corsOriginsSplit) + { + if (client.FindCorsOrigin(corsOrigin) == null) + { + client.AddCorsOrigin(corsOrigin); + } + } + } + + if (permissions != null) + { + await _permissionDataSeeder.SeedAsync(ClientPermissionValueProvider.ProviderName, name, permissions); + } + + return await _clientRepository.UpdateAsync(client); + } + + #endregion +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xml b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xml new file mode 100644 index 000000000..00e1d9a1c --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xsd b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj new file mode 100644 index 000000000..fe8585fb9 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj @@ -0,0 +1,47 @@ + + + + + + + net8.0 + LY.MicroService.Applications.Single.EntityFrameworkCore + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md new file mode 100644 index 000000000..67e42e5c3 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md @@ -0,0 +1,97 @@ +# LY.MicroService.Applications.Single.EntityFrameworkCore + +Monolithic Application Database Migration Module, providing comprehensive application database migration functionality. + +[简体中文](./README.md) + +## Features + +* Integrated Audit Logging data migration +* Integrated Setting Management data migration +* Integrated Permission Management data migration +* Integrated Feature Management data migration +* Integrated Notification System data migration +* Integrated Message Service data migration +* Integrated Platform Management data migration +* Integrated Localization Management data migration +* Integrated Identity Authentication data migration +* Integrated IdentityServer data migration +* Integrated OpenIddict data migration +* Integrated Text Templating data migration +* Integrated Webhooks Management data migration +* Integrated Task Management data migration +* Integrated SaaS multi-tenancy data migration +* Support for database migration event handling +* Provides database migration service + +## Module Dependencies + +```csharp +[DependsOn( + typeof(AbpSaasEntityFrameworkCoreModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpNotificationsEntityFrameworkCoreModule), + typeof(AbpMessageServiceEntityFrameworkCoreModule), + typeof(PlatformEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpIdentityServerEntityFrameworkCoreModule), + typeof(AbpOpenIddictEntityFrameworkCoreModule), + typeof(AbpTextTemplatingEntityFrameworkCoreModule), + typeof(WebhooksManagementEntityFrameworkCoreModule), + typeof(TaskManagementEntityFrameworkCoreModule), + typeof(AbpWeChatModule), + typeof(AbpDataDbMigratorModule) +)] +``` + +## Configuration + +```json +{ + "ConnectionStrings": { + "SingleDbMigrator": "Your database connection string" + } +} +``` + +## Basic Usage + +1. Configure Database Connection String + * Configure SingleDbMigrator connection string in appsettings.json + +2. Add Module Dependency + ```csharp + [DependsOn(typeof(SingleMigrationsEntityFrameworkCoreModule))] + public class YourModule : AbpModule + { + // ... + } + ``` + +## Database Tables Description + +* AbpAuditLogs - Audit logging data +* Identity Related Tables - User, role, claims and other authentication related data +* IdentityServer Related Tables - Client, API resources, identity resources and other OAuth/OpenID Connect related data +* OpenIddict Related Tables - OpenID Connect authentication related data +* AbpPermissionGrants - Permission authorization data +* AbpSettings - System settings data +* AbpFeatures - Feature data +* AbpNotifications - Notification system data +* AbpMessageService - Message service data +* Platform Related Tables - Platform management related data +* AbpLocalization - Localization management data +* AbpTextTemplates - Text template data +* AbpWebhooks - Webhooks management data +* AbpTasks - Task management data +* Saas Related Tables - Tenant, edition and other multi-tenancy related data + +## More Information + +* [ABP Documentation](https://docs.abp.io) +* [OpenIddict Documentation](https://documentation.openiddict.com) +* [IdentityServer4 Documentation](https://identityserver4.readthedocs.io) diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md new file mode 100644 index 000000000..a96b753ab --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md @@ -0,0 +1,97 @@ +# LY.MicroService.Applications.Single.EntityFrameworkCore + +单体应用数据迁移模块,提供完整的应用程序数据库迁移功能。 + +[English](./README.EN.md) + +## 功能特性 + +* 集成审计日志数据迁移 +* 集成设置管理数据迁移 +* 集成权限管理数据迁移 +* 集成特性管理数据迁移 +* 集成通知系统数据迁移 +* 集成消息服务数据迁移 +* 集成平台管理数据迁移 +* 集成本地化管理数据迁移 +* 集成身份认证数据迁移 +* 集成IdentityServer数据迁移 +* 集成OpenIddict数据迁移 +* 集成文本模板数据迁移 +* 集成Webhooks管理数据迁移 +* 集成任务管理数据迁移 +* 集成SaaS多租户数据迁移 +* 支持数据库迁移事件处理 +* 提供数据库迁移服务 + +## 模块依赖 + +```csharp +[DependsOn( + typeof(AbpSaasEntityFrameworkCoreModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpNotificationsEntityFrameworkCoreModule), + typeof(AbpMessageServiceEntityFrameworkCoreModule), + typeof(PlatformEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpIdentityServerEntityFrameworkCoreModule), + typeof(AbpOpenIddictEntityFrameworkCoreModule), + typeof(AbpTextTemplatingEntityFrameworkCoreModule), + typeof(WebhooksManagementEntityFrameworkCoreModule), + typeof(TaskManagementEntityFrameworkCoreModule), + typeof(AbpWeChatModule), + typeof(AbpDataDbMigratorModule) +)] +``` + +## 配置项 + +```json +{ + "ConnectionStrings": { + "SingleDbMigrator": "你的数据库连接字符串" + } +} +``` + +## 基本用法 + +1. 配置数据库连接字符串 + * 在appsettings.json中配置SingleDbMigrator连接字符串 + +2. 添加模块依赖 + ```csharp + [DependsOn(typeof(SingleMigrationsEntityFrameworkCoreModule))] + public class YourModule : AbpModule + { + // ... + } + ``` + +## 数据库表说明 + +* AbpAuditLogs - 审计日志数据 +* Identity相关表 - 用户、角色、声明等身份认证相关数据 +* IdentityServer相关表 - 客户端、API资源、身份资源等OAuth/OpenID Connect相关数据 +* OpenIddict相关表 - OpenID Connect认证相关数据 +* AbpPermissionGrants - 权限授权数据 +* AbpSettings - 系统设置数据 +* AbpFeatures - 功能特性数据 +* AbpNotifications - 通知系统数据 +* AbpMessageService - 消息服务数据 +* Platform相关表 - 平台管理相关数据 +* AbpLocalization - 本地化管理数据 +* AbpTextTemplates - 文本模板数据 +* AbpWebhooks - Webhooks管理数据 +* AbpTasks - 任务管理数据 +* Saas相关表 - 租户、版本等多租户相关数据 + +## 更多信息 + +* [ABP文档](https://docs.abp.io) +* [OpenIddict文档](https://documentation.openiddict.com) +* [IdentityServer4文档](https://identityserver4.readthedocs.io) diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs new file mode 100644 index 000000000..75ae423ed --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs @@ -0,0 +1,242 @@ +using LINGYUN.Abp.BackgroundTasks; +using LINGYUN.Abp.BackgroundTasks.Internal; +using LINGYUN.Abp.Saas.Tenants; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DistributedLocking; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EntityFrameworkCore.Migrations; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Guids; +using Volo.Abp.Identity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.PermissionManagement; +using Volo.Abp.Uow; +using IdentityRole = Volo.Abp.Identity.IdentityRole; +using IdentityUser = Volo.Abp.Identity.IdentityUser; + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore; +public class SingleDbMigrationEventHandler : + EfCoreDatabaseMigrationEventHandlerBase, + IDistributedEventHandler> +{ + protected AbpBackgroundTasksOptions Options { get; } + protected IJobStore JobStore { get; } + protected IJobScheduler JobScheduler { get; } + protected IGuidGenerator GuidGenerator { get; } + protected IdentityUserManager IdentityUserManager { get; } + protected IdentityRoleManager IdentityRoleManager { get; } + protected IPermissionDataSeeder PermissionDataSeeder { get; } + + public SingleDbMigrationEventHandler( + ICurrentTenant currentTenant, + IUnitOfWorkManager unitOfWorkManager, + ITenantStore tenantStore, + IAbpDistributedLock abpDistributedLock, + IDistributedEventBus distributedEventBus, + ILoggerFactory loggerFactory, + IGuidGenerator guidGenerator, + IdentityUserManager identityUserManager, + IdentityRoleManager identityRoleManager, + IPermissionDataSeeder permissionDataSeeder, + IJobStore jobStore, + IJobScheduler jobScheduler, + IOptions options) + : base("SingleDbMigrator", currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) + { + GuidGenerator = guidGenerator; + IdentityUserManager = identityUserManager; + IdentityRoleManager = identityRoleManager; + PermissionDataSeeder = permissionDataSeeder; + JobStore = jobStore; + JobScheduler = jobScheduler; + Options = options.Value; + } + public async virtual Task HandleEventAsync(EntityDeletedEto eventData) + { + // 租户删除时移除轮询作业 + var pollingJob = BuildPollingJobInfo(eventData.Entity.Id, eventData.Entity.Name); + await JobScheduler.RemoveAsync(pollingJob); + await JobStore.RemoveAsync(pollingJob.Id); + + var cleaningJob = BuildCleaningJobInfo(eventData.Entity.Id, eventData.Entity.Name); + await JobScheduler.RemoveAsync(cleaningJob); + await JobStore.RemoveAsync(cleaningJob.Id); + + var checkingJob = BuildCheckingJobInfo(eventData.Entity.Id, eventData.Entity.Name); + await JobScheduler.RemoveAsync(checkingJob); + await JobStore.RemoveAsync(checkingJob.Id); + } + + protected async override Task AfterTenantCreated(TenantCreatedEto eventData, bool schemaMigrated) + { + if (!schemaMigrated) + { + return; + } + + using (CurrentTenant.Change(eventData.Id)) + { + await QueueBackgroundJobAsync(eventData); + + await SeedTenantDefaultRoleAsync(eventData); + await SeedTenantAdminAsync(eventData); + } + } + + protected async virtual Task QueueBackgroundJobAsync(TenantCreatedEto eventData) + { + var pollingJob = BuildPollingJobInfo(eventData.Id, eventData.Name); + await JobStore.StoreAsync(pollingJob); + await JobScheduler.QueueAsync(pollingJob); + + var cleaningJob = BuildCleaningJobInfo(eventData.Id, eventData.Name); + await JobStore.StoreAsync(cleaningJob); + await JobScheduler.QueueAsync(cleaningJob); + + var checkingJob = BuildCheckingJobInfo(eventData.Id, eventData.Name); + await JobStore.StoreAsync(checkingJob); + await JobScheduler.QueueAsync(checkingJob); + } + + protected virtual JobInfo BuildPollingJobInfo(Guid tenantId, string tenantName) + { + return new JobInfo + { + Id = tenantId.ToString() + "_Polling", + Name = nameof(BackgroundPollingJob), + Group = "Polling", + Description = "Polling tasks to be executed", + Args = new Dictionary() { { nameof(JobInfo.TenantId), tenantId } }, + Status = JobStatus.Running, + BeginTime = DateTime.Now, + CreationTime = DateTime.Now, + Cron = Options.JobFetchCronExpression, + JobType = JobType.Period, + Priority = JobPriority.High, + Source = JobSource.System, + LockTimeOut = Options.JobFetchLockTimeOut, + TenantId = tenantId, + Type = typeof(BackgroundPollingJob).AssemblyQualifiedName, + }; + } + + protected virtual JobInfo BuildCleaningJobInfo(Guid tenantId, string tenantName) + { + return new JobInfo + { + Id = tenantId.ToString() + "_Cleaning", + Name = nameof(BackgroundCleaningJob), + Group = "Cleaning", + Description = "Cleaning tasks to be executed", + Args = new Dictionary() { { nameof(JobInfo.TenantId), tenantId } }, + Status = JobStatus.Running, + BeginTime = DateTime.Now, + CreationTime = DateTime.Now, + Cron = Options.JobCleanCronExpression, + JobType = JobType.Period, + Priority = JobPriority.High, + Source = JobSource.System, + TenantId = tenantId, + Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName, + }; + } + + protected virtual JobInfo BuildCheckingJobInfo(Guid tenantId, string tenantName) + { + return new JobInfo + { + Id = tenantId.ToString() + "_Checking", + Name = nameof(BackgroundCheckingJob), + Group = "Checking", + Description = "Checking tasks to be executed", + Args = new Dictionary() { { nameof(JobInfo.TenantId), tenantId } }, + Status = JobStatus.Running, + BeginTime = DateTime.Now, + CreationTime = DateTime.Now, + Cron = Options.JobCheckCronExpression, + LockTimeOut = Options.JobCheckLockTimeOut, + JobType = JobType.Period, + Priority = JobPriority.High, + Source = JobSource.System, + TenantId = tenantId, + Type = typeof(BackgroundCheckingJob).AssemblyQualifiedName, + }; + } + + protected async virtual Task SeedTenantDefaultRoleAsync(TenantCreatedEto eventData) + { + // 默认用户 + var roleId = GuidGenerator.Create(); + var defaultRole = new IdentityRole(roleId, "Users", eventData.Id) + { + IsStatic = true, + IsPublic = true, + IsDefault = true, + }; + (await IdentityRoleManager.CreateAsync(defaultRole)).CheckErrors(); + + // 所有用户都应该具有查询用户权限, 用于IM场景 + await PermissionDataSeeder.SeedAsync( + RolePermissionValueProvider.ProviderName, + defaultRole.Name, + new string[] + { + IdentityPermissions.UserLookup.Default, + IdentityPermissions.Users.Default + }, + tenantId: eventData.Id); + } + + protected async virtual Task SeedTenantAdminAsync(TenantCreatedEto eventData) + { + const string tenantAdminUserName = "admin"; + const string tenantAdminRoleName = "admin"; + Guid tenantAdminRoleId; + if (!await IdentityRoleManager.RoleExistsAsync(tenantAdminRoleName)) + { + tenantAdminRoleId = GuidGenerator.Create(); + var tenantAdminRole = new IdentityRole(tenantAdminRoleId, tenantAdminRoleName, eventData.Id) + { + IsStatic = true, + IsPublic = true + }; + (await IdentityRoleManager.CreateAsync(tenantAdminRole)).CheckErrors(); + } + else + { + var tenantAdminRole = await IdentityRoleManager.FindByNameAsync(tenantAdminRoleName); + tenantAdminRoleId = tenantAdminRole.Id; + } + + var adminUserId = GuidGenerator.Create(); + if (eventData.Properties.TryGetValue("AdminUserId", out var userIdString) && + Guid.TryParse(userIdString, out var adminUserGuid)) + { + adminUserId = adminUserGuid; + } + var adminEmailAddress = eventData.Properties.GetOrDefault("AdminEmail") ?? "admin@abp.io"; + var adminPassword = eventData.Properties.GetOrDefault("AdminPassword") ?? "1q2w3E*"; + + var tenantAdminUser = await IdentityUserManager.FindByNameAsync(adminEmailAddress); + if (tenantAdminUser == null) + { + tenantAdminUser = new IdentityUser( + adminUserId, + tenantAdminUserName, + adminEmailAddress, + eventData.Id); + + tenantAdminUser.AddRole(tenantAdminRoleId); + + // 创建租户管理用户 + (await IdentityUserManager.CreateAsync(tenantAdminUser)).CheckErrors(); + (await IdentityUserManager.AddPasswordAsync(tenantAdminUser, adminPassword)).CheckErrors(); + } + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs new file mode 100644 index 000000000..1247b3499 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs @@ -0,0 +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, 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>() + .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); + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs new file mode 100644 index 000000000..1a1312e6d --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs @@ -0,0 +1,58 @@ +using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using LINGYUN.Abp.Notifications.EntityFrameworkCore; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.TaskManagement.EntityFrameworkCore; +using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; +using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; +using LINGYUN.Platform.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using Volo.Abp.AuditLogging.EntityFrameworkCore; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Identity.EntityFrameworkCore; +using Volo.Abp.IdentityServer.EntityFrameworkCore; +using Volo.Abp.OpenIddict.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore; + +[ConnectionStringName("SingleDbMigrator")] +public class SingleMigrationsDbContext : AbpDbContext +{ + public SingleMigrationsDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureAuditLogging(); + modelBuilder.ConfigureIdentity(); + modelBuilder.ConfigureIdentityServer(); + modelBuilder.ConfigureOpenIddict(); + modelBuilder.ConfigureSaas(); + modelBuilder.ConfigureFeatureManagement(); + modelBuilder.ConfigureSettingManagement(); + modelBuilder.ConfigurePermissionManagement(); + modelBuilder.ConfigureTextTemplating(); + modelBuilder.ConfigureTaskManagement(); + modelBuilder.ConfigureWebhooksManagement(); + modelBuilder.ConfigurePlatform(); + modelBuilder.ConfigureLocalization(); + modelBuilder.ConfigureNotifications(); + modelBuilder.ConfigureNotificationsDefinition(); + modelBuilder.ConfigureMessageService(); + modelBuilder.ConfigureDataProtectionManagement(); + modelBuilder.ConfigureWebhooksManagement(); + + modelBuilder.ConfigureProjectName(); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs new file mode 100644 index 000000000..623f5d40b --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs @@ -0,0 +1,48 @@ +using LINGYUN.Abp.AuditLogging.EntityFrameworkCore; +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.Identity.EntityFrameworkCore; +using LINGYUN.Abp.IdentityServer.EntityFrameworkCore; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using LINGYUN.Abp.Notifications.EntityFrameworkCore; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using LINGYUN.Abp.TaskManagement.EntityFrameworkCore; +using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; +using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; +using LINGYUN.Abp.WeChat; +using LINGYUN.Platform.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.FeatureManagement.EntityFrameworkCore; +using Volo.Abp.Modularity; +using Volo.Abp.OpenIddict.EntityFrameworkCore; +using Volo.Abp.PermissionManagement.EntityFrameworkCore; +using Volo.Abp.SettingManagement.EntityFrameworkCore; + +namespace LY.MicroService.Applications.Single.EntityFrameworkCore; + +[DependsOn( + typeof(AbpSaasEntityFrameworkCoreModule), + typeof(AbpAuditLoggingEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpFeatureManagementEntityFrameworkCoreModule), + typeof(AbpNotificationsEntityFrameworkCoreModule), + typeof(AbpMessageServiceEntityFrameworkCoreModule), + typeof(PlatformEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpIdentityServerEntityFrameworkCoreModule), + typeof(AbpOpenIddictEntityFrameworkCoreModule), + typeof(AbpTextTemplatingEntityFrameworkCoreModule), + typeof(WebhooksManagementEntityFrameworkCoreModule), + typeof(TaskManagementEntityFrameworkCoreModule), + typeof(AbpWeChatModule), + typeof(AbpDataDbMigratorModule) + )] +public class SingleMigrationsEntityFrameworkCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAbpDbContext(); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj new file mode 100644 index 000000000..0eaa24015 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName.CompanyName.ProjectName.Application.Contracts.csproj @@ -0,0 +1,27 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + PackageName.CompanyName.ProjectName.Application.Contracts + PackageName.CompanyName.ProjectName.Application.Contracts + false + false + false + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs new file mode 100644 index 000000000..5fed2b916 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureDefinitionProvider.cs @@ -0,0 +1,18 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; + +namespace PackageName.CompanyName.ProjectName.Features; + +public class ProjectNameFeatureDefinitionProvider : FeatureDefinitionProvider +{ + public override void Define(IFeatureDefinitionContext context) + { + var group = context.AddGroup(ProjectNameFeatureNames.GroupName, L("Features:ProjectName")); + } + + private static ILocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs new file mode 100644 index 000000000..6389fbcf6 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Features/ProjectNameFeatureNames.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName.Features; + +public static class ProjectNameFeatureNames +{ + public const string GroupName = "ProjectName"; +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs new file mode 100644 index 000000000..6f132d9a3 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/IProjectNameDynamicQueryableAppService.cs @@ -0,0 +1,10 @@ +using LINGYUN.Abp.Dynamic.Queryable; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 提供动态查询接口定义 +/// +/// 实体dto类型 +public interface IProjectNameDynamicQueryableAppService : IDynamicQueryableAppService +{ +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs new file mode 100644 index 000000000..4a170551b --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissionDefinitionProvider.cs @@ -0,0 +1,22 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace PackageName.CompanyName.ProjectName.Permissions; + +public class ProjectNamePermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var group = context.AddGroup(ProjectNamePermissions.GroupName, L("Permission:ProjectName")); + + group.AddPermission( + ProjectNamePermissions.ManageSettings, + L("Permission:ManageSettings")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs new file mode 100644 index 000000000..98a957ff9 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/Permissions/ProjectNamePermissions.cs @@ -0,0 +1,8 @@ +namespace PackageName.CompanyName.ProjectName.Permissions; + +public static class ProjectNamePermissions +{ + public const string GroupName = "ProjectName"; + + public const string ManageSettings = GroupName + ".ManageSettings"; +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs new file mode 100644 index 000000000..eb0b2fb15 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameApplicationContractsModule.cs @@ -0,0 +1,17 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.Features; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpFeaturesModule), + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationContractsModule), + typeof(AbpDynamicQueryableApplicationContractsModule), + typeof(ProjectNameDomainSharedModule))] +public class ProjectNameApplicationContractsModule : AbpModule +{ +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs new file mode 100644 index 000000000..4b5bb260d --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application.Contracts/PackageName/CompanyName/ProjectName/ProjectNameRemoteServiceConsts.cs @@ -0,0 +1,7 @@ +namespace PackageName.CompanyName.ProjectName; + +public static class ProjectNameRemoteServiceConsts +{ + public const string RemoteServiceName = "ProjectName"; + public const string ModuleName = "ProjectName"; +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj new file mode 100644 index 000000000..cf195e665 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName.CompanyName.ProjectName.Application.csproj @@ -0,0 +1,26 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.Application + PackageName.CompanyName.ProjectName.Application + false + false + false + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs new file mode 100644 index 000000000..496140dfe --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameAppServiceBase.cs @@ -0,0 +1,13 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Application.Services; + +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameAppServiceBase : ApplicationService +{ + protected ProjectNameAppServiceBase() + { + LocalizationResource = typeof(ProjectNameResource); + ObjectMapperContext = typeof(ProjectNameApplicationModule); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs new file mode 100644 index 000000000..0ace9b456 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationMapperProfile.cs @@ -0,0 +1,10 @@ +using AutoMapper; + +namespace PackageName.CompanyName.ProjectName; + +public class ProjectNameApplicationMapperProfile : Profile +{ + public ProjectNameApplicationMapperProfile() + { + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs new file mode 100644 index 000000000..6e1cf009f --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameApplicationModule.cs @@ -0,0 +1,27 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationModule), + typeof(ProjectNameDomainModule), + typeof(ProjectNameApplicationContractsModule), + typeof(AbpDynamicQueryableApplicationModule))] +public class ProjectNameApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs new file mode 100644 index 000000000..e20348b53 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableAppServiceBase.cs @@ -0,0 +1,19 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using PackageName.CompanyName.ProjectName.Localization; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 提供动态查询接口实现 +/// +/// 实体类型 +/// 实体dto类型 +public abstract class ProjectNameDynamicQueryableAppServiceBase : + DynamicQueryableAppService, + IProjectNameDynamicQueryableAppService +{ + protected ProjectNameDynamicQueryableAppServiceBase() + { + LocalizationResource = typeof(ProjectNameResource); + ObjectMapperContext = typeof(ProjectNameApplicationModule); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs new file mode 100644 index 000000000..fd7a017ea --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Application/System/Linq/Expressions/ExpressionFuncExtensions.cs @@ -0,0 +1,32 @@ +using Volo.Abp.Specifications; + +namespace System.Linq.Expressions; + +internal static class ExpressionFuncExtensions +{ + public static Expression> AndIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.And(first, second); + } + + return first; + } + + public static Expression> OrIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.Or(first, second); + } + + return first; + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj new file mode 100644 index 000000000..aa6f4772b --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName.CompanyName.ProjectName.Dapr.Client.csproj @@ -0,0 +1,19 @@ + + + + + + + net8.0 + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs new file mode 100644 index 000000000..ca16b0bf1 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Dapr.Client/PackageName/CompanyName/ProjectName/ProjectNameDaprClientModule.cs @@ -0,0 +1,18 @@ +using LINGYUN.Abp.Dapr.Client; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpDaprClientModule), + typeof(ProjectNameApplicationContractsModule))] +public class ProjectNameDaprClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddStaticDaprClientProxies( + typeof(ProjectNameApplicationContractsModule).Assembly, + ProjectNameRemoteServiceConsts.RemoteServiceName); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj new file mode 100644 index 000000000..cd98bbcf9 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName.CompanyName.ProjectName.Domain.Shared.csproj @@ -0,0 +1,30 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + PackageName.CompanyName.ProjectName.Domain.Shared + PackageName.CompanyName.ProjectName.Domain.Shared + false + false + false + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs new file mode 100644 index 000000000..b0c280d5a --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/ProjectNameResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace PackageName.CompanyName.ProjectName.Localization; + +[LocalizationResourceName("ProjectName")] +public class ProjectNameResource +{ +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json new file mode 100644 index 000000000..d14e6f1dd --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/en.json @@ -0,0 +1,8 @@ +{ + "culture": "en", + "texts": { + "Features:ProjectName": "ProjectName", + "Permission:ProjectName": "ProjectName", + "Permission:ManageSettings": "Manage Settings" + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..c85b3754a --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/Localization/Resources/zh-Hans.json @@ -0,0 +1,8 @@ +{ + "culture": "zh-Hans", + "texts": { + "Features:ProjectName": "ProjectName", + "Permission:ProjectName": "ProjectName", + "Permission:ManageSettings": "管理设置" + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs new file mode 100644 index 000000000..6634ceb15 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfiguration.cs @@ -0,0 +1,16 @@ +using System; +using Volo.Abp.ObjectExtending.Modularity; + +namespace PackageName.CompanyName.ProjectName.ObjectExtending; + +public class ProjectNameModuleExtensionConfiguration : ModuleExtensionConfiguration +{ + public ProjectNameModuleExtensionConfiguration ConfigureProjectName( + Action configureAction) + { + return this.ConfigureEntity( + ProjectNameModuleExtensionConsts.EntityNames.Entity, + configureAction + ); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs new file mode 100644 index 000000000..fabfd40c9 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConfigurationDictionaryExtensions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.ObjectExtending.Modularity; + +namespace PackageName.CompanyName.ProjectName.ObjectExtending; + +public static class ProjectNameModuleExtensionConfigurationDictionaryExtensions +{ + public static ModuleExtensionConfigurationDictionary ConfigureProjectName( + this ModuleExtensionConfigurationDictionary modules, + Action configureAction) + { + return modules.ConfigureModule( + ProjectNameModuleExtensionConsts.ModuleName, + configureAction + ); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs new file mode 100644 index 000000000..1973ef9b6 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ObjectExtending/ProjectNameModuleExtensionConsts.cs @@ -0,0 +1,11 @@ +namespace PackageName.CompanyName.ProjectName.ObjectExtending; + +public static class ProjectNameModuleExtensionConsts +{ + public const string ModuleName = "ProjectName"; + + public static class EntityNames + { + public const string Entity = "Entity"; + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs new file mode 100644 index 000000000..ec682b498 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameDomainSharedModule.cs @@ -0,0 +1,32 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpLocalizationModule))] +public class ProjectNameDomainSharedModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add() + .AddVirtualJson("/PackageName/CompanyName/ProjectName/Localization/Resources"); + }); + + Configure(options => + { + options.MapCodeNamespace(ProjectNameErrorCodes.Namespace, typeof(ProjectNameResource)); + }); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs new file mode 100644 index 000000000..b2383ee40 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain.Shared/PackageName/CompanyName/ProjectName/ProjectNameErrorCodes.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName; + +public static class ProjectNameErrorCodes +{ + public const string Namespace = "ProjectName"; +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj new file mode 100644 index 000000000..2cccd0944 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName.CompanyName.ProjectName.Domain.csproj @@ -0,0 +1,27 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.Domain + PackageName.CompanyName.ProjectName.Domain + false + false + false + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs new file mode 100644 index 000000000..290e09398 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/IProjectNameBasicRepository.cs @@ -0,0 +1,54 @@ +using LINGYUN.Abp.DataProtection; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Specifications; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 基本仓储接口 +/// +/// 实体类型 +/// 实体主键类型 +public interface IProjectNameBasicRepository : IDataProtectionRepository + where TEntity : class, IEntity +{ + /// + /// 获取过滤后的实体数量 + /// + /// + /// + /// + Task GetCountAsync( + ISpecification specification, + CancellationToken cancellationToken = default); + /// + /// 获取过滤后的实体列表(分页) + /// + /// + /// + /// + /// + /// + /// + Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + int skipCount = 0, + CancellationToken cancellationToken = default); + /// + /// 获取过滤后的实体列表 + /// + /// + /// + /// + /// + /// + Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs new file mode 100644 index 000000000..a18947c6c --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDbProperties.cs @@ -0,0 +1,11 @@ +namespace PackageName.CompanyName.ProjectName; + +public static class ProjectNameDbProperties +{ + public static string DbTablePrefix { get; set; } = "ProjectName_"; + + public static string DbSchema { get; set; } = null; + + + public const string ConnectionStringName = "ProjectName"; +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs new file mode 100644 index 000000000..79c7af553 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainMapperProfile.cs @@ -0,0 +1,11 @@ +using AutoMapper; + +namespace PackageName.CompanyName.ProjectName; + +public class ProjectNameDomainMapperProfile : Profile +{ + public ProjectNameDomainMapperProfile() + { + + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs new file mode 100644 index 000000000..401aa849e --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/ProjectNameDomainModule.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.DataProtection; +using Microsoft.Extensions.DependencyInjection; +using PackageName.CompanyName.ProjectName.ObjectExtending; +using Volo.Abp.AutoMapper; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.Modularity; +using Volo.Abp.ObjectExtending.Modularity; +using Volo.Abp.Threading; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpDataProtectionModule), + typeof(ProjectNameDomainSharedModule))] +public class ProjectNameDomainModule : AbpModule +{ + private static readonly OneTimeRunner OneTimeRunner = new(); + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + }); + } + + public override void PostConfigureServices(ServiceConfigurationContext context) + { + OneTimeRunner.Run(() => + { + // 扩展实体配置 + //ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( + // ProjectNameModuleExtensionConsts.ModuleName, + // ProjectNameModuleExtensionConsts.EntityNames.Entity, + // typeof(Entity) + //); + }); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs new file mode 100644 index 000000000..cdfdef118 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettingDefinitionProvider.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Settings; + +namespace PackageName.CompanyName.ProjectName.Settings; + +public class ProjectNameSettingDefinitionProvider : SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs new file mode 100644 index 000000000..deb0b7b71 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/PackageName/CompanyName/ProjectName/Settings/ProjectNameSettings.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName.Settings; + +public static class ProjectNameSettings +{ + public const string GroupName = "ProjectName"; +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs new file mode 100644 index 000000000..fd7a017ea --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs @@ -0,0 +1,32 @@ +using Volo.Abp.Specifications; + +namespace System.Linq.Expressions; + +internal static class ExpressionFuncExtensions +{ + public static Expression> AndIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.And(first, second); + } + + return first; + } + + public static Expression> OrIf( + this Expression> first, + bool condition, + Expression> second) + { + if (condition) + { + return ExpressionFuncExtender.Or(first, second); + } + + return first; + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj new file mode 100644 index 000000000..05ba83db3 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName.CompanyName.ProjectName.EntityFrameworkCore.csproj @@ -0,0 +1,37 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.EntityFrameworkCore + PackageName.CompanyName.ProjectName.EntityFrameworkCore + false + false + false + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs new file mode 100644 index 000000000..2d68cf660 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/EfCoreProjectNameRepository.cs @@ -0,0 +1,77 @@ +using LINGYUN.Abp.DataProtection; +using LINGYUN.Abp.DataProtection.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Specifications; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; +/// +/// 实现基本接口 +/// +/// 实体类型 +/// 实体主键类型 +public abstract class EfCoreProjectNameRepository : + EfCoreDataProtectionRepository, + IProjectNameBasicRepository + where TEntity : class, IEntity +{ + protected EfCoreProjectNameRepository( + IDbContextProvider dbContextProvider, + IDataAuthorizationService dataAuthorizationService, + IEntityTypeFilterBuilder entityTypeFilterBuilder) + : base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder) + { + } + + public async virtual Task GetCountAsync( + ISpecification specification, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(specification.ToExpression()) + .CountAsync(GetCancellationToken(cancellationToken)); + } + + public async virtual Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + int skipCount = 0, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(specification.ToExpression()) + .OrderBy(GetSortingOrDefault(sorting)) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public async virtual Task> GetListAsync( + ISpecification specification, + string sorting = nameof(IEntity.Id), + int maxResultCount = 10, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(specification.ToExpression()) + .OrderBy(GetSortingOrDefault(sorting)) + .Take(maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + protected virtual string GetSortingOrDefault(string sorting = nameof(IEntity.Id)) + { + if (sorting.IsNullOrWhiteSpace()) + { + return nameof(IEntity.Id); + } + return sorting; + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs new file mode 100644 index 000000000..c39c2923e --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/IProjectNameDbContext.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)] +public interface IProjectNameDbContext : IEfCoreDbContext +{ +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs new file mode 100644 index 000000000..5cb2c015b --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContext.cs @@ -0,0 +1,21 @@ +using LINGYUN.Abp.DataProtection.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[ConnectionStringName(ProjectNameDbProperties.ConnectionStringName)] +public class ProjectNameDbContext : AbpDataProtectionDbContext, IProjectNameDbContext +{ + public ProjectNameDbContext( + DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureProjectName(); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs new file mode 100644 index 000000000..d9ffcb9ca --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextFactory.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using System.IO; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; +public class ProjectNameDbContextFactory : IDesignTimeDbContextFactory +{ + public ProjectNameDbContext CreateDbContext(string[] args) + { + var configuration = BuildConfiguration(); + var connectionString = configuration.GetConnectionString("ProjectName"); + + DbContextOptionsBuilder builder = null; + +#if MySQL + builder = new DbContextOptionsBuilder() + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); +#elif SqlServer + builder = new DbContextOptionsBuilder() + .UseSqlServer(connectionString); +#elif Sqlite + builder = new DbContextOptionsBuilder() + .UseSqlite(connectionString); +#elif Oracle + builder = new DbContextOptionsBuilder() + .UseOracle(connectionString); +#elif OracleDevart + builder = (DbContextOptionsBuilder) new DbContextOptionsBuilder() + .UseOracle(connectionString); +#elif PostgreSql + builder = new DbContextOptionsBuilder() + .UseNpgsql(connectionString); +#endif + + return new ProjectNameDbContext(builder!.Options); + } + + private static IConfigurationRoot BuildConfiguration() + { + var builder = new ConfigurationBuilder() + .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../PackageName.CompanyName.ProjectName.DbMigrator/")) + .AddJsonFile("appsettings.json", optional: false) + .AddJsonFile("appsettings.Development.json", optional: true); + + return builder.Build(); + } +} + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..726b4ec9a --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbContextModelCreatingExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using System; +using Volo.Abp; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public static class ProjectNameDbContextModelCreatingExtensions +{ + public static void ConfigureProjectName( + this ModelBuilder builder, + Action optionsAction = null) + { + Check.NotNull(builder, nameof(builder)); + + var options = new ProjectNameModelBuilderConfigurationOptions( + ProjectNameDbProperties.DbTablePrefix, + ProjectNameDbProperties.DbSchema + ); + optionsAction?.Invoke(options); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs new file mode 100644 index 000000000..74a4a39bc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationEventHandler.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DistributedLocking; +using Volo.Abp.EntityFrameworkCore.Migrations; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public class ProjectNameDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase +{ + protected IDataSeeder DataSeeder { get; } + + public ProjectNameDbMigrationEventHandler( + IDataSeeder dataSeeder, + ITenantStore tenantStore, + ICurrentTenant currentTenant, + IUnitOfWorkManager unitOfWorkManager, + IAbpDistributedLock abpDistributedLock, + IDistributedEventBus distributedEventBus, + ILoggerFactory loggerFactory) + : base( + ConnectionStringNameAttribute.GetConnStringName(), + currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory) + { + DataSeeder = dataSeeder; + } + + protected async override Task SeedAsync(Guid? tenantId) + { + await DataSeeder.SeedAsync(tenantId); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs new file mode 100644 index 000000000..70d5d69e8 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameDbMigrationService.cs @@ -0,0 +1,58 @@ +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.Saas.Tenants; +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.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public class ProjectNameDbMigrationService : EfCoreRuntimeDbMigratorBase, ITransientDependency +{ + protected IDataSeeder DataSeeder { get; } + protected IDbSchemaMigrator DbSchemaMigrator { get; } + protected ITenantRepository TenantRepository { get; } + + public ProjectNameDbMigrationService( + IDataSeeder dataSeeder, + IDbSchemaMigrator dbSchemaMigrator, + ITenantRepository tenantRepository, + ICurrentTenant currentTenant, + IUnitOfWorkManager unitOfWorkManager, + IServiceProvider serviceProvider, + IAbpDistributedLock abpDistributedLock, + IDistributedEventBus distributedEventBus, + ILoggerFactory loggerFactory) + : base( + ConnectionStringNameAttribute.GetConnStringName(), + unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) + { + DataSeeder = dataSeeder; + DbSchemaMigrator = dbSchemaMigrator; + TenantRepository = tenantRepository; + } + + protected async override Task LockAndApplyDatabaseMigrationsAsync() + { + await base.LockAndApplyDatabaseMigrationsAsync(); + + var tenants = await TenantRepository.GetListAsync(); + foreach (var tenant in tenants.Where(x => x.IsActive)) + { + await LockAndApplyDatabaseWithTenantMigrationsAsync(tenant.Id); + } + } + + protected async override Task SeedAsync() + { + Logger.LogInformation($"Executing {(!CurrentTenant.IsAvailable ? "host" : CurrentTenant.Name ?? CurrentTenant.GetId().ToString())} database seed..."); + + await DataSeeder.SeedAsync(CurrentTenant.Id); + } +} \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs new file mode 100644 index 000000000..90b369745 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEfCoreQueryableExtensions.cs @@ -0,0 +1,6 @@ +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public static class ProjectNameEfCoreQueryableExtensions +{ + // 在此聚合仓储服务的扩展方法 +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs new file mode 100644 index 000000000..b18f43183 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs @@ -0,0 +1,76 @@ +using LINGYUN.Abp.Data.DbMigrator; +using LINGYUN.Abp.DataProtection.EntityFrameworkCore; +using LINGYUN.Abp.Saas.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; +#if MySQL +using Volo.Abp.EntityFrameworkCore.MySQL; +#elif SqlServer +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Microsoft.EntityFrameworkCore.Infrastructure; +#elif Sqlite +using Volo.Abp.EntityFrameworkCore.Sqlite; +#elif Oracle +using Volo.Abp.EntityFrameworkCore.Oracle; +#elif OracleDevart +using Volo.Abp.EntityFrameworkCore.Oracle.Devart; +#elif PostgreSql +using Volo.Abp.EntityFrameworkCore.PostgreSql; +#endif + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[DependsOn( + typeof(ProjectNameDomainModule), + typeof(AbpDataDbMigratorModule), + typeof(AbpDataProtectionEntityFrameworkCoreModule), +#if MySQL + typeof(AbpEntityFrameworkCoreMySQLModule), +#elif SqlServer + typeof(AbpEntityFrameworkCoreSqlServerModule), +#elif Sqlite + typeof(AbpEntityFrameworkCoreSqliteModule), +#elif Oracle + typeof(AbpEntityFrameworkCoreOracleModule), +#elif OracleDevart + typeof(AbpEntityFrameworkCoreOracleDevartModule), +#elif PostgreSql + typeof(AbpEntityFrameworkCorePostgreSqlModule), +#endif + typeof(AbpSaasEntityFrameworkCoreModule))] +public class ProjectNameEntityFrameworkCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + // 配置Ef + Configure(options => + { +#if MySQL + options.UseMySQL(); + options.UseMySQL(); +#elif SqlServer + options.UseSqlServer(); + options.UseSqlServer(builder => + { + // see https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-ver16 + // builder.UseCompatibilityLevel(150); + }); +#elif Sqlite + options.UseSqlite(); + options.UseSqlite(); +#elif Oracle || OracleDevart + options.UseOracle(); + options.UseOracle(); +#elif PostgreSql + options.UseNpgsql(); + options.UseNpgsql(); +#endif + }); + + context.Services.AddAbpDbContext(options => + { + options.AddDefaultRepositories(); + }); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs new file mode 100644 index 000000000..5849eb902 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.EntityFrameworkCore/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameModelBuilderConfigurationOptions.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; +using Volo.Abp.EntityFrameworkCore.Modeling; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public class ProjectNameModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions +{ + public ProjectNameModelBuilderConfigurationOptions( + [NotNull] string tablePrefix = "", + [CanBeNull] string schema = null) + : base( + tablePrefix, + schema) + { + + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj new file mode 100644 index 000000000..30cf00fd9 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName.CompanyName.ProjectName.HttpApi.Client.csproj @@ -0,0 +1,24 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + PackageName.CompanyName.ProjectName.HttpApi.Client + PackageName.CompanyName.ProjectName.HttpApi.Client + false + false + false + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs new file mode 100644 index 000000000..831ba468a --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi.Client/PackageName/CompanyName/ProjectName/ProjectNameHttpApiClientModule.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpHttpClientModule), + typeof(ProjectNameApplicationContractsModule))] +public class ProjectNameHttpApiClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddStaticHttpClientProxies( + typeof(ProjectNameApplicationContractsModule).Assembly, + ProjectNameRemoteServiceConsts.RemoteServiceName); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj new file mode 100644 index 000000000..0f2375f61 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName.CompanyName.ProjectName.HttpApi.csproj @@ -0,0 +1,25 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.HttpApi + PackageName.CompanyName.ProjectName.HttpApi + false + false + false + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs new file mode 100644 index 000000000..7345f99ea --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameControllerBase.cs @@ -0,0 +1,12 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameControllerBase : AbpControllerBase +{ + protected ProjectNameControllerBase() + { + LocalizationResource = typeof(ProjectNameResource); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs new file mode 100644 index 000000000..41cfe834a --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameDynamicQueryableControllerBase.cs @@ -0,0 +1,17 @@ +using LINGYUN.Abp.Dynamic.Queryable; +using PackageName.CompanyName.ProjectName.Localization; + +namespace PackageName.CompanyName.ProjectName; +/// +/// 提供动态查询控制器实现 +/// +/// 实体dto类型 +public abstract class ProjectNameDynamicQueryableControllerBase : DynamicQueryableControllerBase +{ + protected ProjectNameDynamicQueryableControllerBase( + IDynamicQueryableAppService service) + : base(service) + { + LocalizationResource = typeof(ProjectNameResource); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs new file mode 100644 index 000000000..3a68e60da --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.HttpApi/PackageName/CompanyName/ProjectName/ProjectNameHttpApiModule.cs @@ -0,0 +1,42 @@ +using PackageName.CompanyName.ProjectName.Localization; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Validation.Localization; +using LINGYUN.Abp.Dynamic.Queryable; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAspNetCoreMvcModule), + typeof(ProjectNameApplicationContractsModule), + typeof(AbpDynamicQueryableHttpApiModule))] +public class ProjectNameHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(ProjectNameHttpApiModule).Assembly); + }); + + PreConfigure(options => + { + options.AddAssemblyResource( + typeof(ProjectNameResource), + typeof(ProjectNameApplicationContractsModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpValidationResource)); + }); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj new file mode 100644 index 000000000..51af57d0b --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName.CompanyName.ProjectName.SettingManagement.csproj @@ -0,0 +1,27 @@ + + + + + + + net8.0 + PackageName.CompanyName.ProjectName.SettingManagement + PackageName.CompanyName.ProjectName.SettingManagement + false + false + false + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs new file mode 100644 index 000000000..dff74dddb --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/IProjectNameSettingAppService.cs @@ -0,0 +1,7 @@ +using LINGYUN.Abp.SettingManagement; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +public interface IProjectNameSettingAppService : ISettingAppService, IUserSettingAppService +{ +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs new file mode 100644 index 000000000..4fab9bdd6 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingAppService.cs @@ -0,0 +1,106 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Authorization; +using PackageName.CompanyName.ProjectName.Permissions; +using PackageName.CompanyName.ProjectName.Localization; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; +using Volo.Abp.Features; +using Volo.Abp.MultiTenancy; +using Volo.Abp.SettingManagement; +using Volo.Abp.Settings; +using Volo.Abp.Users; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +public class ProjectNameSettingAppService : ApplicationService, IProjectNameSettingAppService +{ + protected ISettingManager SettingManager { get; } + protected ISettingDefinitionManager SettingDefinitionManager { get; } + + public ProjectNameSettingAppService( + ISettingManager settingManager, + ISettingDefinitionManager settingDefinitionManager) + { + SettingManager = settingManager; + SettingDefinitionManager = settingDefinitionManager; + LocalizationResource = typeof(ProjectNameResource); + } + + public virtual async Task GetAllForCurrentTenantAsync() + { + return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString()); + } + + [Authorize] + public virtual async Task GetAllForCurrentUserAsync() + { + return await GetAllForProviderAsync(UserSettingValueProvider.ProviderName, CurrentUser.GetId().ToString()); + } + + public virtual async Task GetAllForGlobalAsync() + { + return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null); + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + if (CurrentTenant.IsAvailable) + { + foreach (var setting in input.Settings) + { + await SettingManager.SetForTenantAsync(CurrentTenant.GetId(), setting.Name, setting.Value); + } + + await CurrentUnitOfWork.SaveChangesAsync(); + } + } + + [Authorize] + public virtual async Task SetCurrentUserAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + foreach (var setting in input.Settings) + { + await SettingManager.SetForCurrentUserAsync(setting.Name, setting.Value); + } + + await CurrentUnitOfWork.SaveChangesAsync(); + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + public virtual async Task SetGlobalAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + foreach (var setting in input.Settings) + { + await SettingManager.SetGlobalAsync(setting.Name, setting.Value); + } + + await CurrentUnitOfWork.SaveChangesAsync(); + } + + + protected virtual async Task CheckFeatureAsync() + { + await FeatureChecker.CheckEnabledAsync(SettingManagementFeatures.Enable); + } + + protected virtual async Task GetAllForProviderAsync(string providerName, string providerKey) + { + var settingGroups = new SettingGroupResult(); + + //TODO: 当前项目所有配置项在此定义返回 + + await Task.CompletedTask; + + return settingGroups; + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs new file mode 100644 index 000000000..2c045ba59 --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingController.cs @@ -0,0 +1,69 @@ +using Asp.Versioning; +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using PackageName.CompanyName.ProjectName.Permissions; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +[RemoteService(Name = ProjectNameRemoteServiceConsts.RemoteServiceName)] +[ApiVersion("2.0")] +[Area(ProjectNameRemoteServiceConsts.ModuleName)] +[Route("api/ProjectName/settings")] +public class ProjectNameSettingController : AbpController, IProjectNameSettingAppService +{ + private readonly IProjectNameSettingAppService _settingAppService; + public ProjectNameSettingController(IProjectNameSettingAppService settingAppService) + { + _settingAppService = settingAppService; + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + [HttpPut] + [Route("by-current-tenant")] + public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) + { + await _settingAppService.SetCurrentTenantAsync(input); + } + + [HttpGet] + [Route("by-current-tenant")] + public virtual async Task GetAllForCurrentTenantAsync() + { + return await _settingAppService.GetAllForCurrentTenantAsync(); + } + + [Authorize] + [HttpPut] + [Route("by-current-user")] + public virtual async Task SetCurrentUserAsync(UpdateSettingsDto input) + { + await _settingAppService.SetCurrentTenantAsync(input); + } + + [Authorize] + [HttpGet] + [Route("by-current-user")] + public virtual async Task GetAllForCurrentUserAsync() + { + return await _settingAppService.GetAllForCurrentTenantAsync(); + } + + [Authorize(ProjectNamePermissions.ManageSettings)] + [HttpPut] + [Route("by-global")] + public virtual async Task SetGlobalAsync(UpdateSettingsDto input) + { + await _settingAppService.SetGlobalAsync(input); + } + + [HttpGet] + [Route("by-global")] + public virtual async Task GetAllForGlobalAsync() + { + return await _settingAppService.GetAllForGlobalAsync(); + } +} diff --git a/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs new file mode 100644 index 000000000..914707f4a --- /dev/null +++ b/aspnet-core/templates/aio/content/src/PackageName.CompanyName.ProjectName.SettingManagement/PackageName/CompanyName/ProjectName/SettingManagement/ProjectNameSettingManagementModule.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; +using Volo.Abp.SettingManagement; + +namespace PackageName.CompanyName.ProjectName.SettingManagement; + +[DependsOn( + typeof(AbpSettingManagementApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule), + typeof(AbpSettingManagementDomainModule))] +public class ProjectNameSettingManagementModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(ProjectNameSettingManagementModule).Assembly); + }); + } +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj new file mode 100644 index 000000000..7aefab82c --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName.CompanyName.ProjectName.Application.Tests.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + + false + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs new file mode 100644 index 000000000..f5ae45141 --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestBase.cs @@ -0,0 +1,5 @@ +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameApplicationTestBase : ProjectNameTestBase +{ +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs new file mode 100644 index 000000000..7e9fa658a --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Application.Tests/PackageName/CompanyName/ProjectName/ProjectNameApplicationTestModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(ProjectNameDomainTestModule), + typeof(ProjectNameApplicationModule) + )] +public class ProjectNameApplicationTestModule : AbpModule +{ +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj new file mode 100644 index 000000000..5ca01ede0 --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName.CompanyName.ProjectName.Domain.Tests.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + + false + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs new file mode 100644 index 000000000..471e0adf8 --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestBase.cs @@ -0,0 +1,5 @@ +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameDomainTestBase : ProjectNameTestBase +{ +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs new file mode 100644 index 000000000..f4a8a9d16 --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.Domain.Tests/PackageName/CompanyName/ProjectName/ProjectNameDomainTestModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(ProjectNameTestBaseModule), + typeof(ProjectNameDomainModule) + )] +public class ProjectNameDomainTestModule : AbpModule +{ +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj new file mode 100644 index 000000000..cb9c91e1f --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + + false + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs new file mode 100644 index 000000000..738149b6f --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestBase.cs @@ -0,0 +1,5 @@ +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +public abstract class ProjectNameEntityFrameworkCoreTestBase : ProjectNameTestBase +{ +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs new file mode 100644 index 000000000..da8ce7c6c --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.EntityFrameworkCore.Tests/PackageName/CompanyName/ProjectName/EntityFrameworkCore/ProjectNameEntityFrameworkCoreTestModule.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using System; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName.EntityFrameworkCore; + +[DependsOn( + typeof(ProjectNameTestBaseModule), + typeof(ProjectNameEntityFrameworkCoreModule) + )] +public class ProjectNameEntityFrameworkCoreTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddEntityFrameworkInMemoryDatabase(); + + var databaseName = Guid.NewGuid().ToString(); + + Configure(options => + { + options.Configure(abpDbContextConfigurationContext => + { + abpDbContextConfigurationContext.DbContextOptions.EnableDetailedErrors(); + abpDbContextConfigurationContext.DbContextOptions.EnableSensitiveDataLogging(); + + abpDbContextConfigurationContext.DbContextOptions.UseInMemoryDatabase(databaseName); + }); + }); + + Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions + }); + } +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj new file mode 100644 index 000000000..ae4b6d5bf --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName.CompanyName.ProjectName.TestBase.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + + false + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs new file mode 100644 index 000000000..08aeffccb --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBase.cs @@ -0,0 +1,58 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Modularity; +using Volo.Abp.Testing; +using Volo.Abp.Uow; + +namespace PackageName.CompanyName.ProjectName; + +public abstract class ProjectNameTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected virtual Task WithUnitOfWorkAsync(Func func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + await action(); + + await uow.CompleteAsync(); + } + } + } + + protected virtual Task WithUnitOfWorkAsync(Func> func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + var result = await func(); + await uow.CompleteAsync(); + return result; + } + } + } +} diff --git a/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs new file mode 100644 index 000000000..4564d29b6 --- /dev/null +++ b/aspnet-core/templates/aio/content/tests/PackageName.CompanyName.ProjectName.TestBase/PackageName/CompanyName/ProjectName/ProjectNameTestBaseModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.Features; +using Volo.Abp.MemoryDb; +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpTestBaseModule), + typeof(AbpAuthorizationModule), + typeof(AbpFeaturesModule), + typeof(AbpMemoryDbModule) + )] +public class ProjectNameTestBaseModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAlwaysAllowAuthorization(); + } +} From 5e6ea87b98e070defc5436aa00d3fc3f82500b3b Mon Sep 17 00:00:00 2001 From: feijie Date: Tue, 31 Dec 2024 17:34:46 +0800 Subject: [PATCH 15/29] =?UTF-8?q?=E2=9C=A8=20feat(=E8=BF=81=E7=A7=BB):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E4=BB=A5=E6=94=AF=E6=8C=81=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E4=B8=8A=E4=B8=8B=E6=96=87=E9=80=89=E6=8B=A9=E5=92=8C?= =?UTF-8?q?SQL=E8=84=9A=E6=9C=AC=E7=94=9F=E6=88=90=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aio/content/migrations/Migrate.ps1 | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100755 aspnet-core/templates/aio/content/migrations/Migrate.ps1 diff --git a/aspnet-core/templates/aio/content/migrations/Migrate.ps1 b/aspnet-core/templates/aio/content/migrations/Migrate.ps1 new file mode 100755 index 000000000..522aef17e --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/Migrate.ps1 @@ -0,0 +1,203 @@ +# 数据库迁移脚本 + +# 导入必要的模块 +using namespace System.Management.Automation.Host + +# 加入环境变量FROM_MIGRATION,使其在Program.cs文件中可以进行判断 +$env:FROM_MIGRATION = "true" + +# 定义项目路径 +$projectPath = Resolve-Path (Join-Path $PSScriptRoot "..") + +# 定义可用的DbContext +$dbContexts = @{ + "1" = @{ + Name = "PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql" + Context = "SingleMigrationsDbContext" + Factory = "SingleMigrationsDbContextFactory" + } +} + +# 显示DbContext选择菜单 +function Show-DbContextMenu { + $host.UI.RawUI.BackgroundColor = "Black" + $host.UI.RawUI.ForegroundColor = "White" + Clear-Host + + Write-Host "========================================" -ForegroundColor Cyan + Write-Host " 数据库迁移上下文选择" -ForegroundColor Yellow + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "" + Write-Host "请选择要迁移的数据库上下文:" -ForegroundColor Green + foreach ($key in $dbContexts.Keys) { + $context = $dbContexts[$key] + Write-Host "[$key] " -NoNewline -ForegroundColor Magenta + Write-Host "$($context.Name)" -ForegroundColor White + } + Write-Host "" +} + +# 选择DbContext +function Select-DbContext { + Show-DbContextMenu + + while ($true) { + $choice = Read-Host "请输入数字选择" + if ($dbContexts.ContainsKey($choice)) { + return $dbContexts[$choice] + } + Write-Host "无效的选择,请重新输入。" -ForegroundColor Red + } +} + +# 获取迁移名称 +function Get-MigrationName { + $defaultName = "AddNewMigration_" + (Get-Date -Format "yyyyMMdd_HHmmss") + $migrationName = Read-Host "请输入迁移名称 (留空将使用默认名称: $defaultName)" + + return ($migrationName ? $migrationName : $defaultName) +} + +# 执行数据库迁移 +function Invoke-DatabaseMigration($dbContext, $migrationName) { + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "正在执行数据库迁移..." -ForegroundColor Green + Write-Host "上下文: " -NoNewline -ForegroundColor Yellow + Write-Host "$($dbContext.Name)" -ForegroundColor White + Write-Host "迁移名称: " -NoNewline -ForegroundColor Yellow + Write-Host "$migrationName" -ForegroundColor White + Write-Host "项目路径: " -NoNewline -ForegroundColor Yellow + Write-Host "$projectPath" -ForegroundColor White + Write-Host "========================================" -ForegroundColor Cyan + + # 切换到项目目录并执行迁移 + Push-Location $projectPath + try { + dotnet ef migrations add $migrationName --project "migrations/$($dbContext.Name)" --context "$($dbContext.Context)" + } + finally { + Pop-Location + } +} + +# 获取所有迁移文件 +function Get-AllMigrations($dbContext) { + Push-Location $projectPath + try { + $migrations = @(dotnet ef migrations list --project "migrations/$($dbContext.Name)" --context "$($dbContext.Context)") + return $migrations | Where-Object { $_ -match '\S' } # 过滤空行 + } + finally { + Pop-Location + } +} + +# 选择起始迁移 +function Select-FromMigration($dbContext) { + $migrations = Get-AllMigrations -dbContext $dbContext + + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "可用的迁移文件:" -ForegroundColor Yellow + Write-Host "========================================" -ForegroundColor Cyan + + for ($i = 0; $i -lt $migrations.Count; $i++) { + Write-Host "[$i] " -NoNewline -ForegroundColor Magenta + Write-Host "$($migrations[$i])" -ForegroundColor White + } + + Write-Host "[A] " -NoNewline -ForegroundColor Magenta + Write-Host "生成所有迁移的SQL脚本" -ForegroundColor White + Write-Host "[L] " -NoNewline -ForegroundColor Magenta + Write-Host "仅生成最新迁移的SQL脚本" -ForegroundColor White + + while ($true) { + $choice = Read-Host "请选择起始迁移文件" + if ($choice -eq "A" -or $choice -eq "a") { + return $null + } + if ($choice -eq "L" -or $choice -eq "l") { + if ($migrations.Count -gt 1) { + return $migrations[$migrations.Count - 2] + } + return $null + } + if ([int]::TryParse($choice, [ref]$null)) { + $index = [int]$choice + if ($index -ge 0 -and $index -lt $migrations.Count) { + return $migrations[$index] + } + } + Write-Host "无效的选择,请重新输入。" -ForegroundColor Red + } +} + +# 生成SQL脚本 +function Export-SqlScript($dbContext, $migrationName) { + $choice = Read-Host "是否生成SQL迁移脚本?(Y/N)" + + if ($choice -eq "Y" -or $choice -eq "y") { + $sqlFileName = (Get-Date -Format "yyyyMMddHHmm") + ".sql" + $initSqlPath = Join-Path $projectPath "InitSql" + $contextSqlPath = Join-Path $initSqlPath $dbContext.Name + + # 确保InitSql和上下文特定目录存在 + if (-not (Test-Path $initSqlPath)) { + New-Item -ItemType Directory -Path $initSqlPath | Out-Null + } + if (-not (Test-Path $contextSqlPath)) { + New-Item -ItemType Directory -Path $contextSqlPath | Out-Null + } + + $sqlFilePath = Join-Path $contextSqlPath $sqlFileName + + # 选择起始迁移 + $fromMigration = Select-FromMigration -dbContext $dbContext + + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "正在生成SQL脚本..." -ForegroundColor Green + Write-Host "输出路径: " -NoNewline -ForegroundColor Yellow + Write-Host "$sqlFilePath" -ForegroundColor White + if ($fromMigration) { + Write-Host "起始迁移: " -NoNewline -ForegroundColor Yellow + Write-Host "$fromMigration" -ForegroundColor White + } + Write-Host "========================================" -ForegroundColor Cyan + + # 切换到项目目录并生成SQL脚本 + Push-Location $projectPath + try { + if ($fromMigration) { + dotnet ef migrations script $fromMigration --project "migrations/$($dbContext.Name)" --context "$($dbContext.Context)" --output $sqlFilePath + } + else { + dotnet ef migrations script --project "migrations/$($dbContext.Name)" --context "$($dbContext.Context)" --output $sqlFilePath + } + } + finally { + Pop-Location + } + + Write-Host "SQL脚本已生成: " -NoNewline -ForegroundColor Green + Write-Host "$sqlFilePath" -ForegroundColor White + } +} + +# 主执行流程 +try { + $dbContext = Select-DbContext + $migrationName = Get-MigrationName + Invoke-DatabaseMigration -dbContext $dbContext -migrationName $migrationName + + # 生成SQL脚本 + Export-SqlScript -dbContext $dbContext -migrationName $migrationName + + Write-Host "迁移完成!" -ForegroundColor Green +} +catch { + Write-Host "迁移过程中发生错误:" -ForegroundColor Red + Write-Host $_.Exception.Message -ForegroundColor Red +} +finally { + Write-Host "`n按任意键退出..." + $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") +} From 2c8e618337bbb7ec1900211662edb4ea2bde0b80 Mon Sep 17 00:00:00 2001 From: feijie Date: Tue, 31 Dec 2024 17:35:10 +0800 Subject: [PATCH 16/29] =?UTF-8?q?=F0=9F=94=A7=20fix(Commands/CreateCommand?= =?UTF-8?q?):=20=E6=9B=B4=E6=96=B0=E6=A8=A1=E6=9D=BF=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=80=BC=20lam=20=E5=92=8C=20laa=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs index 6fc58163f..506b462b8 100644 --- a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs +++ b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/CreateCommand.cs @@ -196,7 +196,7 @@ public string GetUsageInfo() sb.AppendLine("Options:"); sb.AppendLine(""); sb.AppendLine("-pk|--package (default: app)"); - sb.AppendLine("-t|--template (default: lam)"); + sb.AppendLine("-t|--template (default: lam), optional:lam、laa"); sb.AppendLine("-d|--database-provider (if supported by the template)"); sb.AppendLine("-o|--output-folder (default: current folder)"); sb.AppendLine("-v|--version (default: latest version)"); From 634c1af51b7880a576e7eaf0c27afe422918fbeb Mon Sep 17 00:00:00 2001 From: feijie Date: Tue, 31 Dec 2024 17:35:33 +0800 Subject: [PATCH 17/29] =?UTF-8?q?=E2=9C=A8=20feat(=E5=BE=AE=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E6=A8=A1=E5=9D=97):=20=E6=9B=B4=E6=96=B0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E4=B8=8A=E4=B8=8B=E6=96=87=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=A4=9A=E7=A7=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=B1=BB=E5=9E=8B=E5=B9=B6=E8=B0=83=E6=95=B4=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=90=8D=E7=A7=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dockerfile | 2 +- ...rviceApplicationsSingleModule.Configure.cs | 26 +++++++++++-- .../MicroServiceApplicationsSingleModule.cs | 37 +++++++++++++++++-- ...me.CompanyName.ProjectName.AIO.Host.csproj | 16 +++----- .../Properties/launchSettings.json | 4 +- 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile index aee09fd66..f96f82dd4 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Dockerfile @@ -16,4 +16,4 @@ VOLUME [ "./app/Modules" ] RUN apt update RUN apt install wget -y -ENTRYPOINT ["dotnet", "LY.MicroService.Applications.Single.dll"] +ENTRYPOINT ["dotnet", "PackageName.CompanyName.ProjectName.AIO.dll"] diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs index cbc4e883a..8c40891fa 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs @@ -552,7 +552,7 @@ private void ConfigureVirtualFileSystem() { Configure(options => { - options.FileSets.AddEmbedded("LY.MicroService.Applications.Single"); + options.FileSets.AddEmbedded("PackageName.CompanyName.ProjectName.AIO"); }); } @@ -567,12 +567,30 @@ private void ConfigureIdempotent() private void ConfigureDbContext() { + // 配置Ef Configure(options => { - // AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 - // options.UseNpgsql(); - +#if MySQL options.UseMySQL(); + options.UseMySQL(); +#elif SqlServer + options.UseSqlServer(); + options.UseSqlServer(builder => + { + // see https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-ver16 + // builder.UseCompatibilityLevel(150); + }); +#elif Sqlite + options.UseSqlite(); + options.UseSqlite(); +#elif Oracle || OracleDevart + options.UseOracle(); + options.UseOracle(); +#elif PostgreSql + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + options.UseNpgsql(); + options.UseNpgsql(); +#endif }); } diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs index ceb61611a..c3b097cba 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.cs @@ -102,6 +102,8 @@ using LINGYUN.Platform.HttpApi; using LINGYUN.Platform.Settings.VueVbenAdmin; using LINGYUN.Platform.Theme.VueVbenAdmin; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.SettingManagement; using Volo.Abp; using Volo.Abp.Account.Web; using Volo.Abp.AspNetCore.Authentication.JwtBearer; @@ -111,7 +113,6 @@ 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; @@ -123,8 +124,20 @@ using Volo.Abp.SettingManagement; using Volo.Abp.SettingManagement.EntityFrameworkCore; using Volo.Abp.Threading; -// using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql; +#if MySQL using Volo.Abp.EntityFrameworkCore.MySQL; +#elif SqlServer +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Microsoft.EntityFrameworkCore.Infrastructure; +#elif Sqlite +using Volo.Abp.EntityFrameworkCore.Sqlite; +#elif Oracle +using Volo.Abp.EntityFrameworkCore.Oracle; +#elif OracleDevart +using Volo.Abp.EntityFrameworkCore.Oracle.Devart; +#elif PostgreSql +using Volo.Abp.EntityFrameworkCore.PostgreSql; +#endif namespace PackageName.CompanyName.ProjectName.AIO.Host; @@ -233,8 +246,19 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host; typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理 - // typeof(AbpEntityFrameworkCorePostgreSqlModule), +#if MySQL typeof(AbpEntityFrameworkCoreMySQLModule), +#elif SqlServer + typeof(AbpEntityFrameworkCoreSqlServerModule), +#elif Sqlite + typeof(AbpEntityFrameworkCoreSqliteModule), +#elif Oracle + typeof(AbpEntityFrameworkCoreOracleModule), +#elif OracleDevart + typeof(AbpEntityFrameworkCoreOracleDevartModule), +#elif PostgreSql + typeof(AbpEntityFrameworkCorePostgreSqlModule), +#endif typeof(AbpAliyunSmsModule), typeof(AbpAliyunSettingManagementModule), @@ -323,7 +347,12 @@ namespace PackageName.CompanyName.ProjectName.AIO.Host; typeof(AbpAspNetCoreHttpOverridesModule), typeof(AbpAspNetCoreMvcUiBasicThemeModule), typeof(AbpEventBusModule), - typeof(AbpAutofacModule) + typeof(AbpAutofacModule), + + typeof(ProjectNameApplicationModule), + typeof(ProjectNameHttpApiModule), + typeof(ProjectNameEntityFrameworkCoreModule), + typeof(ProjectNameSettingManagementModule) )] public partial class MicroServiceApplicationsSingleModule : AbpModule { diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj index 136d24605..90b2d8428 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/PackageName.CompanyName.ProjectName.AIO.Host.csproj @@ -33,8 +33,12 @@ - - + + + + + + @@ -265,12 +269,4 @@ - - - - - - - - diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json index 337677308..2d629479f 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/Properties/launchSettings.json @@ -8,7 +8,7 @@ } }, "profiles": { - "LY.MicroService.Applications.Single": { + "PackageName.CompanyName.ProjectName.AIO": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, @@ -17,7 +17,7 @@ "ASPNETCORE_ENVIRONMENT": "Production" } }, - "LY.MicroService.Applications.Single.Development": { + "PackageName.CompanyName.ProjectName.AIO.Development": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, From de3835c6bd774eef9f67cd73a72d97f4eee1be71 Mon Sep 17 00:00:00 2001 From: feijie Date: Tue, 31 Dec 2024 17:36:25 +0800 Subject: [PATCH 18/29] =?UTF-8?q?=F0=9F=94=A7=20refactor(entity):=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=B8=BA?= =?UTF-8?q?PackageName.CompanyName.ProjectName.AIO=E4=BB=A5=E9=80=82?= =?UTF-8?q?=E5=BA=94=E6=96=B0=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📖 docs(db migrator): 更新README文件以反映新的命名空间和项目结构 🗑️ chore(db migrator): 移除未使用的appsettings.PostgreSql.json文件相关内容 --- ...panyName.ProjectName.AIO.DbMigrator.csproj | 3 - .../Program.cs | 4 +- .../README.EN.md | 2 +- .../README.md | 2 +- .../SingleDbMigratorHostedService.cs | 2 +- .../appsettings.MySql.json | 228 ------------------ .../appsettings.PostgreSql.json | 228 ------------------ .../appsettings.SqlServer.json | 228 ------------------ .../appsettings.json | 3 +- .../README.en.md | 4 +- .../README.md | 4 +- .../SingleMigrationsDbContextFactory.cs | 6 +- ...igrationsEntityFrameworkCoreMySqlModule.cs | 2 +- .../DataSeeder/ClientDataSeederContributor.cs | 2 +- ...ProjectName.AIO.EntityFrameworkCore.csproj | 2 +- .../README.EN.md | 2 +- .../README.md | 2 +- .../SingleDbMigrationEventHandler.cs | 2 +- .../SingleDbMigrationService.cs | 2 +- .../SingleMigrationsDbContext.cs | 2 +- ...ngleMigrationsEntityFrameworkCoreModule.cs | 2 +- 21 files changed, 22 insertions(+), 710 deletions(-) delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj index 3fe9a4c81..574414b4c 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj @@ -29,9 +29,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs index 7153c46d4..53d5c10e2 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/Program.cs @@ -15,9 +15,9 @@ public async static Task Main(string[] args) .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) #if DEBUG - .MinimumLevel.Override("LY.MicroService.Applications.Single.DbMigrator", LogEventLevel.Debug) + .MinimumLevel.Override("PackageName.CompanyName.ProjectName.AIO.DbMigrator", LogEventLevel.Debug) #else - .MinimumLevel.Override("LY.MicroService.Applications.Single.DbMigrator", LogEventLevel.Information) + .MinimumLevel.Override("PackageName.CompanyName.ProjectName.AIO.DbMigrator", LogEventLevel.Information) #endif .Enrich.FromLogContext() .WriteTo.Console() diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md index e60db3ab6..83caf7b08 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.EN.md @@ -1,4 +1,4 @@ -# LY.MicroService.Applications.Single.DbMigrator +# PackageName.CompanyName.ProjectName.AIO.DbMigrator Single application database migration tool for automatically executing database migrations and initializing data. diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md index 1a997f51b..28fa306fe 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/README.md @@ -1,4 +1,4 @@ -# LY.MicroService.Applications.Single.DbMigrator +# PackageName.CompanyName.ProjectName.AIO.DbMigrator 单体应用数据库迁移工具,用于自动执行数据库迁移和初始化数据。 diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs index 2c15b65f1..a78908fa1 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorHostedService.cs @@ -1,4 +1,4 @@ -using LY.MicroService.Applications.Single.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json deleted file mode 100644 index d6bbaf791..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.MySql.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "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" - }, - "DistributedLock": { - "IsEnabled": true, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=14" - } - }, - "Elsa": { - "Features": { - "DefaultPersistence": { - "Enabled": true, - "ConnectionStringIdentifier": "Workflow", - "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": "Workflow", - "EntityFrameworkCore": { - "MySql": { - "Enabled": true - } - } - }, - "WorkflowSettings": { - "Enabled": true, - "ConnectionStringIdentifier": "Workflow", - "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.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.connectionStringName": "TaskManagement", - "quartz.dataSource.tkm.provider": "MySqlConnector", - "quartz.jobStore.clustered": "true", - "quartz.serializer.type": "json" - } - }, - "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" - } - } - ] - } -} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json deleted file mode 100644 index 6858f5041..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.PostgreSql.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "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": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;SslMode=Prefer" - }, - "DistributedLock": { - "IsEnabled": true, - "Redis": { - "Configuration": "127.0.0.1,defaultDatabase=14" - } - }, - "Elsa": { - "Features": { - "DefaultPersistence": { - "Enabled": true, - "ConnectionStringIdentifier": "Default", - "EntityFrameworkCore": { - "PostgreSql": { - "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": { - "PostgreSql": { - "Enabled": true - } - } - }, - "WorkflowSettings": { - "Enabled": true, - "ConnectionStringIdentifier": "Default", - "EntityFrameworkCore": { - "PostgreSql": { - "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.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", - "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" - } - } - ] - } -} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json deleted file mode 100644 index 555dab9fb..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.SqlServer.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "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" - } - } - ] - } -} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json index 4a3dae71a..90452ba57 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/appsettings.json @@ -3,8 +3,7 @@ "Kind": "Local" }, "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;SslMode=Prefer"//PostgreSql + "Default": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" }, "StringEncryption": { "DefaultPassPhrase": "s46c5q55nxpeS8Ra", diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md index e1e97c34f..114aad0be 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md @@ -26,7 +26,7 @@ This guide will help you manage MySQL database migrations using the migration sc 2. Select MySQL database context from the menu: ``` - [1] LY.MicroService.Applications.Single.EntityFrameworkCore.MySql + [1] PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql ``` 3. Enter migration name (optional): @@ -45,7 +45,7 @@ After creating the migration, the script will ask if you want to generate SQL sc Generated SQL scripts will be saved in: ``` -aspnet-core/InitSql/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/ +aspnet-core/InitSql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/ ``` ### 3. Apply Migration diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md index 295e1e512..c43698e9c 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md @@ -26,7 +26,7 @@ 2. 在菜单中选择 MySQL 数据库上下文: ``` - [1] LY.MicroService.Applications.Single.EntityFrameworkCore.MySql + [1] PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql ``` 3. 输入迁移名称(可选): @@ -45,7 +45,7 @@ 生成的 SQL 脚本将保存在: ``` -aspnet-core/InitSql/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/ +aspnet-core/InitSql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/ ``` ### 3. 应用迁移 diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs index d34ba6dd0..3a0f90125 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs @@ -1,4 +1,4 @@ -using LY.MicroService.Applications.Single.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; @@ -14,7 +14,7 @@ public SingleMigrationsDbContext CreateDbContext(string[] args) var connectionString = configuration.GetConnectionString("Default"); var builder = new DbContextOptionsBuilder() - .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), b => b.MigrationsAssembly("LY.MicroService.Applications.Single.EntityFrameworkCore.MySql")); + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql")); return new SingleMigrationsDbContext(builder!.Options); } @@ -23,7 +23,7 @@ private static IConfigurationRoot BuildConfiguration() { var builder = new ConfigurationBuilder() .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), - "../LY.MicroService.Applications.Single.DbMigrator/")) + "../PackageName.CompanyName.ProjectName.AIO.DbMigrator/")) .AddJsonFile("appsettings.json", optional: false) .AddJsonFile("appsettings.MySql.json", optional: true); diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs index e15058880..79c9b3a1b 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs @@ -1,4 +1,4 @@ -using LY.MicroService.Applications.Single.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.MySQL; diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs index d3cfdd062..500e07cd0 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/DataSeeder/ClientDataSeederContributor.cs @@ -17,7 +17,7 @@ using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement; -namespace LY.MicroService.Applications.Single.EntityFrameworkCore.DataSeeder; +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DataSeeder; public class ClientDataSeederContributor : IDataSeedContributor, ITransientDependency { diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj index fe8585fb9..52985bc35 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.csproj @@ -5,7 +5,7 @@ net8.0 - LY.MicroService.Applications.Single.EntityFrameworkCore + PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md index 67e42e5c3..bbfb6e980 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.EN.md @@ -1,4 +1,4 @@ -# LY.MicroService.Applications.Single.EntityFrameworkCore +# PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore Monolithic Application Database Migration Module, providing comprehensive application database migration functionality. diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md index a96b753ab..bc72c164e 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/README.md @@ -1,4 +1,4 @@ -# LY.MicroService.Applications.Single.EntityFrameworkCore +# PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore 单体应用数据迁移模块,提供完整的应用程序数据库迁移功能。 diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs index 75ae423ed..395cf4d39 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationEventHandler.cs @@ -20,7 +20,7 @@ using IdentityRole = Volo.Abp.Identity.IdentityRole; using IdentityUser = Volo.Abp.Identity.IdentityUser; -namespace LY.MicroService.Applications.Single.EntityFrameworkCore; +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; public class SingleDbMigrationEventHandler : EfCoreDatabaseMigrationEventHandlerBase, IDistributedEventHandler> diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs index 1247b3499..faa7a1030 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleDbMigrationService.cs @@ -14,7 +14,7 @@ using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; -namespace LY.MicroService.Applications.Single.EntityFrameworkCore; +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; public class SingleDbMigrationService : EfCoreRuntimeDatabaseMigratorBase, ITransientDependency { diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs index 1a1312e6d..1ba308f45 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsDbContext.cs @@ -19,7 +19,7 @@ using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; -namespace LY.MicroService.Applications.Single.EntityFrameworkCore; +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; [ConnectionStringName("SingleDbMigrator")] public class SingleMigrationsDbContext : AbpDbContext diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs index 623f5d40b..60cc95b86 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore/SingleMigrationsEntityFrameworkCoreModule.cs @@ -18,7 +18,7 @@ using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; -namespace LY.MicroService.Applications.Single.EntityFrameworkCore; +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; [DependsOn( typeof(AbpSaasEntityFrameworkCoreModule), From c685fe9fe67213036c584743064c7cc7832bdc13 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:23:41 +0800 Subject: [PATCH 19/29] =?UTF-8?q?=F0=9F=93=9A=20docs(README.zh-Hans.md):?= =?UTF-8?q?=20=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=89=93=E5=8C=85=E5=92=8C=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E5=91=BD=E4=BB=A4=E7=A4=BA=E4=BE=8B=E3=80=82=20?= =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(LocalFileCreateProjectService.cs)?= =?UTF-8?q?:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E6=95=B0=E6=8D=AE=E5=BA=93=E7=AE=A1=E7=90=86=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E5=8F=82=E6=95=B0=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Commands/LocalFileCreateProjectService.cs | 41 ++++++++++++++++--- .../cli/LINGYUN.Abp.Cli/README.zh-Hans.md | 7 ++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/LocalFileCreateProjectService.cs b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/LocalFileCreateProjectService.cs index 49d3eeb0b..facacbf37 100644 --- a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/LocalFileCreateProjectService.cs +++ b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN/Abp/Cli/Commands/LocalFileCreateProjectService.cs @@ -87,7 +87,7 @@ await TryReplacePackageAndCompanyNameWithProjectFile( projectFiles, createArgs.PackageName, createArgs.SolutionName.CompanyName, - createArgs.DatabaseManagementSystem); + dbm); Logger.LogInformation("Rewrite appsettings.json."); await TryReplaceAppSettingsWithProjectFile( @@ -96,6 +96,13 @@ await TryReplaceAppSettingsWithProjectFile( createArgs.SolutionName.CompanyName, createArgs.SolutionName.ProjectName, createArgs.ConnectionString); + + // Logger.LogInformation("Rewrite scripts."); + // await TryReplaceScriptProjectFile( + // projectFiles, + // createArgs.PackageName, + // createArgs.SolutionName.CompanyName, + // dbm); Logger.LogInformation("Rewrite application url."); await TryReplaceApplicationUrlWithProjectFile( @@ -112,7 +119,8 @@ await TryReplaceVersionWithProjectFile( await TryReplacePackageAndCompanyNameWithProjectFolder( projectFiles, createArgs.PackageName, - createArgs.SolutionName.CompanyName); + createArgs.SolutionName.CompanyName, + dbm); Logger.LogInformation($"'{createArgs.SolutionName.ProjectName}' has been successfully created to '{createArgs.OutputFolder}'"); } @@ -203,32 +211,53 @@ protected async virtual Task TryReplaceAppSettingsWithProjectFile( await ReplaceFileTextAsync(projectFile, defaultConnectionString, connectionString); } } + + // + // protected async virtual Task TryReplaceScriptProjectFile( + // List projectFiles, + // string packageName, + // string companyName, + // string dbm = "MySQL") + // { + // var canReplaceFiles = projectFiles.Where(f => !f.IsFolder && f.Name.EndsWith(".bat", StringComparison.OrdinalIgnoreCase) || + // f.Name.EndsWith(".sh", StringComparison.OrdinalIgnoreCase) || + // f.Name.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase)); + // foreach (var projectFile in canReplaceFiles) + // { + // await ReplaceFileTextAsync(projectFile, "PackageName", packageName); + // await ReplaceFileTextAsync(projectFile, "CompanyName", companyName); + // + // await ReplaceFileTextAsync(projectFile, "DatabaseManagementName", dbm); + // } + // } protected async virtual Task TryReplacePackageAndCompanyNameWithProjectFile( List projectFiles, string packageName, string companyName, - DatabaseManagementSystem database = DatabaseManagementSystem.NotSpecified) + string dbm = "MySQL") { var canReplaceFiles = projectFiles.Where(f => !f.IsFolder && !f.Name.Contains("appsettings")); foreach (var projectFile in canReplaceFiles) { await ReplaceFileTextAsync(projectFile, "PackageName", packageName); await ReplaceFileTextAsync(projectFile, "CompanyName", companyName); + await ReplaceFileTextAsync(projectFile, "DatabaseManagementName", dbm); } } protected virtual Task TryReplacePackageAndCompanyNameWithProjectFolder( List projectFiles, string packageName, - string companyName) + string companyName, + string dbm = "MySQL") { var canReplaceFiles = projectFiles .OrderByDescending(f => f.Depth) .OrderByDescending(f => !f.IsFolder); foreach (var projectFile in canReplaceFiles) { - var replaceFileName = projectFile.Name.Replace("PackageName", packageName).Replace("CompanyName", companyName); + var replaceFileName = projectFile.Name.Replace("PackageName", packageName).Replace("CompanyName", companyName).Replace("DatabaseManagementName", dbm); if (File.Exists(projectFile.Name)) { @@ -238,7 +267,7 @@ protected virtual Task TryReplacePackageAndCompanyNameWithProjectFolder( } var canReplacePaths = projectFiles - .Where(projectFile => projectFile.Name.Contains("PackageName") || projectFile.Name.Contains("CompanyName")) + .Where(projectFile => projectFile.Name.Contains("PackageName") || projectFile.Name.Contains("CompanyName") || projectFile.Name.Contains("DatabaseManagementName")) .OrderByDescending(f => f.Depth) .OrderByDescending(f => f.IsFolder); foreach (var projectFile in canReplacePaths) diff --git a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/README.zh-Hans.md b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/README.zh-Hans.md index 61b716992..0bff40e8a 100644 --- a/aspnet-core/framework/cli/LINGYUN.Abp.Cli/README.zh-Hans.md +++ b/aspnet-core/framework/cli/LINGYUN.Abp.Cli/README.zh-Hans.md @@ -8,6 +8,13 @@ dotnet tool install --global LINGYUN.Abp.Cli ``` +打包项目为LINGYUN.Abp.Cli.8.3.0.nupkg + +```shell +dotnet pack -o ./nupkg +dotnet tool install -g LINGYUN.Abp.Cli --version 8.3.0 --add-source ./nupkg +``` + ## 使用方法 ```shell From d2ca25f86f78fe1e8d7f9aa02657bfeb88c34863 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:24:01 +0800 Subject: [PATCH 20/29] =?UTF-8?q?=F0=9F=94=A7=20fix(templates):=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20groupIdentity=20=E4=B8=BA=20"LINGYUN.Abp"?= =?UTF-8?q?=20=E4=BB=A5=E4=BC=98=E5=8C=96=E6=A8=A1=E6=9D=BF=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/aio/content/.template.config/template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnet-core/templates/aio/content/.template.config/template.json b/aspnet-core/templates/aio/content/.template.config/template.json index b2a850a12..d8da1581b 100644 --- a/aspnet-core/templates/aio/content/.template.config/template.json +++ b/aspnet-core/templates/aio/content/.template.config/template.json @@ -5,7 +5,7 @@ "name": "LINGYUN.Abp.AllInOne", "identity": "LINGYUN.Abp.AllInOne", "description": "Abp framework all-in-one template", - "groupIdentity": "LINGYUN.Abp.Application", + "groupIdentity": "LINGYUN.Abp", "shortName": "laa", "tags": { "language": "C#", From f9ef021dd374ddde6bfa153507897a877b00e8de Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:24:23 +0800 Subject: [PATCH 21/29] =?UTF-8?q?=F0=9F=94=A7=20chore(appsettings):=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=BAProjectName=E4=BB=A5?= =?UTF-8?q?=E4=BE=BF=E4=BA=8E=E6=9C=AC=E5=9C=B0=E5=BC=80=E5=8F=91=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E9=85=8D=E7=BD=AE=20=F0=9F=94=A7=20chore(MicroService?= =?UTF-8?q?ApplicationsSingleModule):=20=E4=BF=AE=E5=A4=8DPostgreSql?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=88=B3=E8=A1=8C=E4=B8=BA=E4=BB=A5=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E6=9C=AC=E5=9C=B0=E6=97=B6=E5=8C=BA=E5=86=99=E5=85=A5?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...roServiceApplicationsSingleModule.Configure.cs | 3 ++- .../appsettings.Development.json | 15 +++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs index 8c40891fa..765a6ceb2 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/MicroServiceApplicationsSingleModule.Configure.cs @@ -29,6 +29,7 @@ using LINGYUN.Abp.Wrapper; using LINGYUN.Platform.Localization; using PackageName.CompanyName.ProjectName.AIO.Host.Microsoft.Extensions.DependencyInjection; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; using Medallion.Threading; using Medallion.Threading.Redis; using Microsoft.AspNetCore.Authentication.Cookies; @@ -587,7 +588,7 @@ private void ConfigureDbContext() options.UseOracle(); options.UseOracle(); #elif PostgreSql - AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + System.AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 options.UseNpgsql(); options.UseNpgsql(); #endif diff --git a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json index 4f753c08e..07d801a94 100644 --- a/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json +++ b/aspnet-core/templates/aio/content/host/PackageName.CompanyName.ProjectName.AIO.Host/appsettings.Development.json @@ -36,8 +36,7 @@ } }, "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 + "Default": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456" }, "DistributedLock": { "IsEnabled": true, @@ -51,7 +50,7 @@ "Enabled": true, "ConnectionStringIdentifier": "Default", "EntityFrameworkCore": { - "MySql": { + "DatabaseManagementName": { "Enabled": true } } @@ -74,7 +73,7 @@ "Enabled": true, "ConnectionStringIdentifier": "Default", "EntityFrameworkCore": { - "MySql": { + "DatabaseManagementName": { "Enabled": true } } @@ -83,7 +82,7 @@ "Enabled": true, "ConnectionStringIdentifier": "Default", "EntityFrameworkCore": { - "MySql": { + "DatabaseManagementName": { "Enabled": true } } @@ -100,10 +99,10 @@ "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.dataSource.tkm.connectionString": "Default": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", + "quartz.dataSource.tkm.provider": "DatabaseManagementNameConnector", // "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", -// "quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;", +// "quartz.dataSource.tkm.connectionString": "Default": "Server=127.0.0.1;Database=ProjectName;User Id=root;Password=123456", // "quartz.dataSource.tkm.provider": "Npgsql", "quartz.jobStore.clustered": "true", "quartz.serializer.type": "json" From bbb411f394c5c8d93811b5030d56cfb33ed62fca Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:24:34 +0800 Subject: [PATCH 22/29] =?UTF-8?q?=F0=9F=93=A6=20=E6=9B=B4=E6=96=B0(Directo?= =?UTF-8?q?ry.Packages.props):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9Oracle?= =?UTF-8?q?=E5=92=8CSQLite=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=8F=98=E9=87=8F=E6=9B=BF=E4=BB=A3=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/aio/content/Directory.Packages.props | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/aspnet-core/templates/aio/content/Directory.Packages.props b/aspnet-core/templates/aio/content/Directory.Packages.props index 433f06afb..1d84e88c5 100644 --- a/aspnet-core/templates/aio/content/Directory.Packages.props +++ b/aspnet-core/templates/aio/content/Directory.Packages.props @@ -118,6 +118,10 @@ + + + + @@ -195,7 +199,7 @@ - + @@ -211,7 +215,7 @@ - + From 00d96ec093dd0454e8d33c260f42501bd15a59e0 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:24:57 +0800 Subject: [PATCH 23/29] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20delete(file):=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20MySql=20=E8=BF=81=E7=A7=BB=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=96=87=E4=BB=B6=E4=BB=A5=E6=B8=85=E7=90=86=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FodyWeavers.xml | 4 -- .../FodyWeavers.xsd | 30 ---------- ...tName.AIO.EntityFrameworkCore.MySql.csproj | 22 ------- .../README.en.md | 59 ------------------- .../README.md | 59 ------------------- .../SingleMigrationsDbContextFactory.cs | 32 ---------- ...igrationsEntityFrameworkCoreMySqlModule.cs | 24 -------- 7 files changed, 230 deletions(-) delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml deleted file mode 100644 index be68c182b..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd deleted file mode 100644 index 3f3946e28..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/FodyWeavers.xsd +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj deleted file mode 100644 index 5af36315b..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - net8.0 - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md deleted file mode 100644 index 114aad0be..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.en.md +++ /dev/null @@ -1,59 +0,0 @@ -# MySQL Database Migration Guide - -This guide will help you manage MySQL 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 MySQL 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 MySQL database context from the menu: - ``` - [1] PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql - ``` - -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/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/ -``` - -### 3. Apply Migration - -Generated SQL scripts can be applied to database through: - -1. Using MySQL client tools to execute SQL script directly -2. Or using command line: - ```powershell - mysql -u your_username -p your_database < your_script.sql - ``` diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md deleted file mode 100644 index c43698e9c..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# MySQL 数据库迁移指南 - -本指南将帮助您使用迁移脚本来管理 MySQL 数据库的迁移操作。 - -## 前置条件 - -1. 确保已安装 .NET Core SDK -2. 确保已安装 Entity Framework Core 工具 - ```powershell - dotnet tool install --global dotnet-ef - ``` -3. 确保已正确配置 MySQL 连接字符串 - -## 使用说明 - -### 1. 创建新的迁移 - -1. 在 `aspnet-core/migrations` 目录下运行迁移脚本: - ```powershell - # 使用中文版本 - .\Migrate.ps1 - - # 或使用英文版本 - .\MigrateEn.ps1 - ``` - -2. 在菜单中选择 MySQL 数据库上下文: - ``` - [1] PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql - ``` - -3. 输入迁移名称(可选): - - 直接回车将使用默认名称:`AddNewMigration_yyyyMMdd_HHmmss` - - 或输入自定义名称,如:`AddNewFeature` - -### 2. 生成 SQL 脚本 - -在创建迁移后,脚本会询问是否需要生成 SQL 脚本: - -1. 选择是否生成 SQL 脚本 (Y/N) -2. 如果选择 Y,将提供以下选项: - - `[A]` - 生成所有迁移的 SQL 脚本 - - `[L]` - 仅生成最新迁移的 SQL 脚本 - - `[0-9]` - 从指定的迁移版本开始生成 - -生成的 SQL 脚本将保存在: -``` -aspnet-core/InitSql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/ -``` - -### 3. 应用迁移 - -生成的 SQL 脚本可以通过以下方式应用到数据库: - -1. 使用 MySQL 客户端工具直接执行 SQL 脚本 -2. 或使用命令行: - ```powershell - mysql -u your_username -p your_database < your_script.sql - ``` diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs deleted file mode 100644 index 3a0f90125..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsDbContextFactory.cs +++ /dev/null @@ -1,32 +0,0 @@ -using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Microsoft.Extensions.Configuration; -using System.IO; - -namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql; - -public class SingleMigrationsDbContextFactory : IDesignTimeDbContextFactory -{ - public SingleMigrationsDbContext CreateDbContext(string[] args) - { - var configuration = BuildConfiguration(); - var connectionString = configuration.GetConnectionString("Default"); - - var builder = new DbContextOptionsBuilder() - .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql")); - - return new SingleMigrationsDbContext(builder!.Options); - } - - private static IConfigurationRoot BuildConfiguration() - { - var builder = new ConfigurationBuilder() - .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), - "../PackageName.CompanyName.ProjectName.AIO.DbMigrator/")) - .AddJsonFile("appsettings.json", optional: false) - .AddJsonFile("appsettings.MySql.json", optional: true); - - return builder.Build(); - } -} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs deleted file mode 100644 index 79c9b3a1b..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/SingleMigrationsEntityFrameworkCoreMySqlModule.cs +++ /dev/null @@ -1,24 +0,0 @@ -using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore.MySQL; -using Volo.Abp.Modularity; - -namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql; - -[DependsOn( - typeof(AbpEntityFrameworkCoreMySQLModule), - typeof(SingleMigrationsEntityFrameworkCoreModule) - )] -public class SingleMigrationsEntityFrameworkCoreMySqlModule : AbpModule -{ - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAbpDbContext(); - - Configure(options => - { - options.UseMySQL(); - }); - } -} From 57fc461e540cbe5638b8479e2ef16d42b67cae0b Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:26:36 +0800 Subject: [PATCH 24/29] =?UTF-8?q?=E2=9C=A8=20feat(templates):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84AIO=E7=9A=84EntityFramework=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FodyWeavers.xml | 4 ++ .../FodyWeavers.xsd | 30 ++++++++ ...rameworkCore.DatabaseManagementName.csproj | 27 ++++++++ .../README.en.md | 59 ++++++++++++++++ .../README.md | 59 ++++++++++++++++ .../SingleMigrationsDbContextFactory.cs | 47 +++++++++++++ ...ameworkCoreDatabaseManagementNameModule.cs | 69 +++++++++++++++++++ 7 files changed, 295 insertions(+) create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xml create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xsd create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName.csproj create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.en.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.md create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsDbContextFactory.cs create mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule.cs diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xml b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xml new file mode 100644 index 000000000..be68c182b --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xsd b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName.csproj new file mode 100644 index 000000000..2307cf26f --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName.csproj @@ -0,0 +1,27 @@ + + + + + + + net8.0 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.en.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.en.md new file mode 100644 index 000000000..114aad0be --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.en.md @@ -0,0 +1,59 @@ +# MySQL Database Migration Guide + +This guide will help you manage MySQL 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 MySQL 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 MySQL database context from the menu: + ``` + [1] PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql + ``` + +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/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/ +``` + +### 3. Apply Migration + +Generated SQL scripts can be applied to database through: + +1. Using MySQL client tools to execute SQL script directly +2. Or using command line: + ```powershell + mysql -u your_username -p your_database < your_script.sql + ``` diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.md b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.md new file mode 100644 index 000000000..c43698e9c --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/README.md @@ -0,0 +1,59 @@ +# MySQL 数据库迁移指南 + +本指南将帮助您使用迁移脚本来管理 MySQL 数据库的迁移操作。 + +## 前置条件 + +1. 确保已安装 .NET Core SDK +2. 确保已安装 Entity Framework Core 工具 + ```powershell + dotnet tool install --global dotnet-ef + ``` +3. 确保已正确配置 MySQL 连接字符串 + +## 使用说明 + +### 1. 创建新的迁移 + +1. 在 `aspnet-core/migrations` 目录下运行迁移脚本: + ```powershell + # 使用中文版本 + .\Migrate.ps1 + + # 或使用英文版本 + .\MigrateEn.ps1 + ``` + +2. 在菜单中选择 MySQL 数据库上下文: + ``` + [1] PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql + ``` + +3. 输入迁移名称(可选): + - 直接回车将使用默认名称:`AddNewMigration_yyyyMMdd_HHmmss` + - 或输入自定义名称,如:`AddNewFeature` + +### 2. 生成 SQL 脚本 + +在创建迁移后,脚本会询问是否需要生成 SQL 脚本: + +1. 选择是否生成 SQL 脚本 (Y/N) +2. 如果选择 Y,将提供以下选项: + - `[A]` - 生成所有迁移的 SQL 脚本 + - `[L]` - 仅生成最新迁移的 SQL 脚本 + - `[0-9]` - 从指定的迁移版本开始生成 + +生成的 SQL 脚本将保存在: +``` +aspnet-core/InitSql/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql/ +``` + +### 3. 应用迁移 + +生成的 SQL 脚本可以通过以下方式应用到数据库: + +1. 使用 MySQL 客户端工具直接执行 SQL 脚本 +2. 或使用命令行: + ```powershell + mysql -u your_username -p your_database < your_script.sql + ``` diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsDbContextFactory.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsDbContextFactory.cs new file mode 100644 index 000000000..f9adabc2d --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsDbContextFactory.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; +using System.IO; + +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName; + +public class SingleMigrationsDbContextFactory : IDesignTimeDbContextFactory +{ + public SingleMigrationsDbContext CreateDbContext(string[] args) + { + var configuration = BuildConfiguration(); + var connectionString = configuration.GetConnectionString("Default"); + DbContextOptionsBuilder builder = null; +#if MySQL + builder = new DbContextOptionsBuilder() + .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName")); +#elif SqlServer + builder = new DbContextOptionsBuilder() + .UseSqlServer(connectionString, b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName")); +#elif Sqlite + builder = new DbContextOptionsBuilder() + .UseSqlite(connectionString, b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName")); +#elif Oracle + builder = new DbContextOptionsBuilder() + .UseOracle(connectionString, b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName")); +#elif OracleDevart + builder = (DbContextOptionsBuilder) new DbContextOptionsBuilder() + .UseOracle(connectionString, b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName")); +#elif PostgreSql + builder = new DbContextOptionsBuilder() + .UseNpgsql(connectionString, b => b.MigrationsAssembly("PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName")); +#endif + return new SingleMigrationsDbContext(builder!.Options); + } + + private static IConfigurationRoot BuildConfiguration() + { + var builder = new ConfigurationBuilder() + .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), + "../PackageName.CompanyName.ProjectName.AIO.DbMigrator/")) + .AddJsonFile("appsettings.json", optional: false); + + return builder.Build(); + } +} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule.cs new file mode 100644 index 000000000..6ef5f8205 --- /dev/null +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName/SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule.cs @@ -0,0 +1,69 @@ +using Microsoft.Extensions.DependencyInjection; +using PackageName.CompanyName.ProjectName.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +#if MySQL +using Volo.Abp.EntityFrameworkCore.MySQL; +#elif SqlServer +using Volo.Abp.EntityFrameworkCore.SqlServer; +using Microsoft.EntityFrameworkCore.Infrastructure; +#elif Sqlite +using Volo.Abp.EntityFrameworkCore.Sqlite; +#elif Oracle +using Volo.Abp.EntityFrameworkCore.Oracle; +#elif OracleDevart +using Volo.Abp.EntityFrameworkCore.Oracle.Devart; +#elif PostgreSql +using Volo.Abp.EntityFrameworkCore.PostgreSql; +#endif +using Volo.Abp.Modularity; + +namespace PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName; + +[DependsOn( +#if MySQL + typeof(AbpEntityFrameworkCoreMySQLModule), +#elif SqlServer + typeof(AbpEntityFrameworkCoreSqlServerModule), +#elif Sqlite + typeof(AbpEntityFrameworkCoreSqliteModule), +#elif Oracle + typeof(AbpEntityFrameworkCoreOracleModule), +#elif OracleDevart + typeof(AbpEntityFrameworkCoreOracleDevartModule), +#elif PostgreSql + typeof(AbpEntityFrameworkCorePostgreSqlModule), +#endif + typeof(SingleMigrationsEntityFrameworkCoreModule) + )] +public class SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAbpDbContext(); + + Configure(options => + { +#if MySQL + options.UseMySQL(); + options.UseMySQL(); +#elif SqlServer + options.UseSqlServer(); + options.UseSqlServer(builder => + { + // see https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-ver16 + // builder.UseCompatibilityLevel(150); + }); +#elif Sqlite + options.UseSqlite(); + options.UseSqlite(); +#elif Oracle || OracleDevart + options.UseOracle(); + options.UseOracle(); +#elif PostgreSql + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题 + options.UseNpgsql(); + options.UseNpgsql(); +#endif + }); + } +} From c7403d78937c41cbe9f614140e4052c2dea25592 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:27:25 +0800 Subject: [PATCH 25/29] =?UTF-8?q?=F0=9F=94=A7=20=E4=BF=AE=E6=94=B9(Migrate?= =?UTF-8?q?.ps1):=20=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E5=90=8D=E7=A7=B0=E4=BB=A5=E5=8D=A0=E4=BD=8D?= =?UTF-8?q?=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aspnet-core/templates/aio/content/migrations/Migrate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnet-core/templates/aio/content/migrations/Migrate.ps1 b/aspnet-core/templates/aio/content/migrations/Migrate.ps1 index 522aef17e..b983af60a 100755 --- a/aspnet-core/templates/aio/content/migrations/Migrate.ps1 +++ b/aspnet-core/templates/aio/content/migrations/Migrate.ps1 @@ -12,7 +12,7 @@ $projectPath = Resolve-Path (Join-Path $PSScriptRoot "..") # 定义可用的DbContext $dbContexts = @{ "1" = @{ - Name = "PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql" + Name = "PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName" Context = "SingleMigrationsDbContext" Factory = "SingleMigrationsDbContextFactory" } From 20bbdb44f2d9f3d50c90bdeb8ee0e6b2a9ac86a0 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:27:41 +0800 Subject: [PATCH 26/29] =?UTF-8?q?=F0=9F=9A=9A=20refactor:=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=20SingleDbMigratorModule.Configure.cs=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=B9=B6=E6=9B=B4=E6=96=B0=E9=A1=B9=E7=9B=AE=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...e.CompanyName.ProjectName.AIO.DbMigrator.csproj | 14 +------------- .../SingleDbMigratorModule.Configure.cs | 14 -------------- .../SingleDbMigratorModule.cs | 13 +++---------- 3 files changed, 4 insertions(+), 37 deletions(-) delete mode 100644 aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj index 574414b4c..9b1ba94a1 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/PackageName.CompanyName.ProjectName.AIO.DbMigrator.csproj @@ -23,29 +23,17 @@ - - PreserveNewest - true - PreserveNewest - - - PreserveNewest - - - - - - + diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs deleted file mode 100644 index 0c4baaacb..000000000 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.Configure.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Volo.Abp.Timing; - -namespace PackageName.CompanyName.ProjectName.AIO.DbMigrator; -public partial class SingleDbMigratorModule -{ - private void ConfigureTiming(IConfiguration configuration) - { - Configure(options => - { - configuration.GetSection("Clock").Bind(options); - }); - } -} diff --git a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs index f730fe211..722ceb8fd 100644 --- a/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs +++ b/aspnet-core/templates/aio/content/migrations/PackageName.CompanyName.ProjectName.AIO.DbMigrator/SingleDbMigratorModule.cs @@ -1,6 +1,5 @@ using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; -using Microsoft.Extensions.DependencyInjection; -using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.MySql; +using PackageName.CompanyName.ProjectName.AIO.EntityFrameworkCore.DatabaseManagementName; using Volo.Abp.Autofac; using Volo.Abp.Modularity; @@ -8,15 +7,9 @@ namespace PackageName.CompanyName.ProjectName.AIO.DbMigrator; [DependsOn( typeof(AbpUINavigationVueVbenAdminModule), - // typeof(SingleMigrationsEntityFrameworkCorePostgreSqlModule), - typeof(SingleMigrationsEntityFrameworkCoreMySqlModule), + typeof(SingleMigrationsEntityFrameworkCoreDatabaseManagementNameModule), typeof(AbpAutofacModule) )] -public partial class SingleDbMigratorModule : AbpModule +public class SingleDbMigratorModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - var configuration = context.Services.GetConfiguration(); - ConfigureTiming(configuration); - } } From 8bd88de9ab00a553e2e944e3618d709d2919f6d8 Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 14:37:30 +0800 Subject: [PATCH 27/29] =?UTF-8?q?=F0=9F=94=A7=20chore(Directory.Packages.p?= =?UTF-8?q?rops):=20=E6=9B=B4=E6=96=B0=E5=A4=9A=E4=B8=AA=E5=8C=85=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E8=87=B3=E6=9C=80=E6=96=B0=E4=BB=A5=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E4=BE=9D=E8=B5=96=E7=9A=84=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E6=80=A7=E5=92=8C=E5=AE=89=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aio/content/Directory.Packages.props | 149 +++++++++++------- 1 file changed, 96 insertions(+), 53 deletions(-) diff --git a/aspnet-core/templates/aio/content/Directory.Packages.props b/aspnet-core/templates/aio/content/Directory.Packages.props index 1d84e88c5..f464588df 100644 --- a/aspnet-core/templates/aio/content/Directory.Packages.props +++ b/aspnet-core/templates/aio/content/Directory.Packages.props @@ -7,6 +7,46 @@ 8.0.0 8.0.0 8.0.0 + 3.1.1 + 8.0.0 + 2.6.1 + 1.8.1 + 6.8.0 + 17.8.0 + 1.12.0 + 6.2.0 + 8.2.0 + 3.7.0 + 1.8.6 + 1.0.5 + 1.0.2 + 16.18.9 + 3.0.2 + 6.0.0 + 3.0.0 + 5.1.0 + 4.2.1 + 2.5.3 + 1.5.10 + 2.13.0 + 1.6.9 + 0.34.0 + 13.0.3 + 7.15.1 + 0.9.2 + 20.0.0 + 4.0.0 + 2023.3.0 + 2.0.1 + 2.7.4 + 6.5.0 + 2.0.3 + 1.0.0-beta.11 + 5.0.0 + 5.4.37 + 3.0.712 + 2.1.0 + 5.5.0 true
@@ -216,6 +256,7 @@ + @@ -251,15 +292,15 @@ - - + + - - - + + + @@ -268,41 +309,40 @@ - - - - - - - - + + + + + + + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -468,27 +508,30 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + From f7bea60845f584daafa18edb643852ba5c389c3f Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 15:03:39 +0800 Subject: [PATCH 28/29] =?UTF-8?q?=F0=9F=93=9A=20docs:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=96=87=E6=A1=A3=EF=BC=8C=E6=B7=BB=E5=8A=A0=20labp=20CLI=20?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E5=AE=89=E8=A3=85=E5=92=8C=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E7=9A=84=E8=AF=B4=E6=98=8E=E3=80=82=20?= =?UTF-8?q?=E2=9C=A8=20feat:=20=E6=B7=BB=E5=8A=A0=20labp=20CLI=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=9A=84=E5=AE=89=E8=A3=85=E5=91=BD=E4=BB=A4=E5=92=8C?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=88=9B=E5=BB=BA=E7=A4=BA=E4=BE=8B=E3=80=82?= =?UTF-8?q?=20=F0=9F=93=9D=20update:=20=E6=9B=B4=E6=96=B0=20README=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=EF=BC=8C=E8=B0=83=E6=95=B4=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E5=B9=B6=E8=A1=A5=E5=85=85=20CLI=20=E5=BF=AB=E9=80=9F=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E6=8C=87=E5=8D=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aspnet-core/templates/aio/content/README.md | 10 +- .../templates/aio/content/README.zh-CN.md | 14 ++- docs/startup-aio-readme.en.md | 85 +++++++++++++---- docs/startup-aio-readme.md | 92 +++++++++++++++---- 4 files changed, 160 insertions(+), 41 deletions(-) diff --git a/aspnet-core/templates/aio/content/README.md b/aspnet-core/templates/aio/content/README.md index 7b7520aef..7d7b52ed3 100644 --- a/aspnet-core/templates/aio/content/README.md +++ b/aspnet-core/templates/aio/content/README.md @@ -33,6 +33,12 @@ LINGYUN.Abp.Templates provides two types of project templates based on ABP Frame ## How to Use +### Install labp CLI Tool + +```bash +dotnet tool install --global LINGYUN.Abp.Cli +``` + ### Install Templates ```bash @@ -49,14 +55,14 @@ dotnet new install LINGYUN.Abp.AllInOne.Templates ```bash # Short name: lam (LINGYUN Abp Microservice) -dotnet new lam -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +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) -dotnet new laa -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +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 diff --git a/aspnet-core/templates/aio/content/README.zh-CN.md b/aspnet-core/templates/aio/content/README.zh-CN.md index b93d76220..ae492e5b8 100644 --- a/aspnet-core/templates/aio/content/README.zh-CN.md +++ b/aspnet-core/templates/aio/content/README.zh-CN.md @@ -36,27 +36,33 @@ LINGYUN.Abp.Templates 基于 ABP Framework 提供两种项目模板: ### 安装模板 ```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) -dotnet new lam -n YourCompanyName.YourProjectName -pk YourPackageName -o /path/to/output --dbms MySql --cs "Server=127.0.0.1;Database=YourDatabase;User Id=your_user;Password=your_password;SslMode=None" --no-random-port +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 MyCompanyName.MyProjectName -pk MyPackageName -t laa -o /Users/feijie/Projects/Tests --dbms MySql --cs "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None" --no-random-port +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 ``` ## 运行项目 diff --git a/docs/startup-aio-readme.en.md b/docs/startup-aio-readme.en.md index baa9bb741..6a3871599 100644 --- a/docs/startup-aio-readme.en.md +++ b/docs/startup-aio-readme.en.md @@ -4,16 +4,69 @@ English | [简体中文](startup-aio-readme.md) ## Table of Contents -- [Requirements](#requirements) -- [Project Compilation](#project-compilation) -- [Environment Configuration](#environment-configuration) - - [Required Configuration](#required-configuration) - - [Optional Configuration](#optional-configuration) -- [Database Initialization](#database-initialization) -- [Service Startup](#service-startup) -- [Configuration Details](#configuration-details) +- [Quick Start with CLI](#quick-start-with-cli) + - [Requirements](#cli-requirements) + - [Install CLI Tool](#install-cli-tool) + - [Create Project](#create-project) + - [Run Project](#run-project) +- [Source Code Startup](#source-code-startup) + - [Requirements](#requirements) + - [Project Compilation](#project-compilation) + - [Environment Configuration](#environment-configuration) + - [Required Configuration](#required-configuration) + - [Optional Configuration](#optional-configuration) + - [Database Initialization](#database-initialization) + - [Service Startup](#service-startup) + - [Configuration Details](#configuration-details) +- [Common Issues](#common-issues) + +## Quick Start with CLI + +### CLI Requirements -## Requirements +- .NET 8.0 SDK +- Database (support any of the following): + - MySQL + - SQL Server + - SQLite + - Oracle + - Oracle Devart + - PostgreSQL +- Redis + +### Install CLI Tool + +```bash +dotnet tool install --global LINGYUN.Abp.Cli +``` + +### Create 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 +``` + +Parameter Description: +- `-pk` or `--package-name`: Package name +- `-t` or `--template`: Template type, use `laa` for All-in-One template +- `-o` or `--output`: Output directory +- `--dbms`: Database type, supports MySql, SqlServer, Sqlite, Oracle, OracleDevart, PostgreSql +- `--cs`: Database connection string +- `--no-random-port`: Do not use random port + +### Run Project + +After creating the project, navigate to the project directory: + +```bash +cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.AIO.Host +dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development" +``` + +## Source Code Startup + +### Requirements - .NET 8.0 SDK - Database (support any of the following): @@ -23,7 +76,7 @@ English | [简体中文](startup-aio-readme.md) - Redis - Docker (optional) -## Project Compilation +### Project Compilation 1. Ensure .NET 8.0 SDK is installed 2. Execute the following command in the project root directory to compile the entire project: @@ -34,9 +87,9 @@ English | [简体中文](startup-aio-readme.md) 3. Open the `LY.MicroService.Applications.Single` solution in your IDE for debugging or publishing -## Environment Configuration +### Environment Configuration -### Required Configuration +#### Required Configuration #### 1. Database Configuration @@ -181,7 +234,7 @@ The following configurations are applicable for monolithic distributed architect } ``` -## Database Initialization +### Database Initialization 1. Run database migration script: @@ -210,15 +263,15 @@ Taking PostgreSQL as an example: - Run the `LY.MicroService.Applications.Single.DbMigrator` project - Wait for migration to complete, basic table data will be initialized -## Service Startup +### Service Startup 1. Run the `LY.MicroService.Applications.Single` project 2. Access Swagger API documentation in your browser: - URL: http://127.0.0.1:30000/swagger -## Configuration Details +### Configuration Details -### 1. Basic Configuration +#### 1. Basic Configuration #### Application Configuration diff --git a/docs/startup-aio-readme.md b/docs/startup-aio-readme.md index 605585796..bb0c4540d 100644 --- a/docs/startup-aio-readme.md +++ b/docs/startup-aio-readme.md @@ -4,16 +4,70 @@ ## 目录 -- [环境要求](#环境要求) -- [项目编译](#项目编译) -- [环境配置](#环境配置) - - [必选配置](#必选配置) - - [可选配置](#可选配置) -- [数据库初始化](#数据库初始化) -- [服务启动](#服务启动) -- [配置说明](#配置说明) +- [CLI 快速启动](#cli快速启动) + - [环境要求](#cli环境要求) + - [安装命令行工具](#安装命令行工具) + - [创建项目](#创建项目) + - [运行项目](#运行项目) +- [源码启动](#源码启动) + - [环境要求](#环境要求) + - [项目编译](#项目编译) + - [环境配置](#环境配置) + - [必选配置](#必选配置) + - [可选配置](#可选配置) + - [数据库初始化](#数据库初始化) + - [服务启动](#服务启动) + - [配置说明](#配置说明) +- [常见问题](#常见问题) + +## CLI 快速启动 + +### CLI 环境要求 -## 环境要求 +- .NET 8.0 SDK +- 数据库(支持以下任一种): + - MySQL + - SQL Server + - SQLite + - Oracle + - Oracle Devart + - PostgreSQL +- Redis + +### 安装命令行工具 + +```bash +dotnet tool install --global LINGYUN.Abp.Cli +``` + +### 创建项目 + +```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 +``` + +参数说明: + +- `-pk` 或 `--package-name`: 包名 +- `-t` 或 `--template`: 模板类型,使用 `laa` 表示单体应用模板 +- `-o` 或 `--output`: 输出目录 +- `--dbms`: 数据库类型,支持 MySql、SqlServer、Sqlite、Oracle、OracleDevart、PostgreSql +- `--cs`: 数据库连接字符串 +- `--no-random-port`: 不使用随机端口 + +### 运行项目 + +创建项目后,进入项目目录: + +```bash +cd /path/to/output/host/YourPackageName.YourCompanyName.YourProjectName.AIO.Host +dotnet run --launch-profile "YourPackageName.YourCompanyName.YourProjectName.Development" +``` + +## 源码启动 + +### 环境要求 - .NET 8.0 SDK - 数据库(支持以下任一种): @@ -23,7 +77,7 @@ - Redis - Docker(可选) -## 项目编译 +### 项目编译 1. 确保已安装 .NET 8.0 SDK 2. 在项目根目录执行以下命令编译整个项目: @@ -34,9 +88,9 @@ 3. 使用 IDE 打开 `LY.MicroService.Applications.Single` 解决方案进行调试或发布 -## 环境配置 +### 环境配置 -### 必选配置 +#### 必选配置 #### 1. 数据库配置 @@ -181,7 +235,7 @@ Redis 配置示例: } ``` -## 数据库初始化 +### 数据库初始化 1. 运行数据库迁移脚本: @@ -210,15 +264,15 @@ Redis 配置示例: - 运行 `LY.MicroService.Applications.Single.DbMigrator` 项目 - 等待数据迁移完成,基础表数据将被初始化 -## 服务启动 +### 服务启动 1. 运行 `LY.MicroService.Applications.Single` 项目 2. 在浏览器中访问 Swagger 接口文档: - URL: http://127.0.0.1:30000/swagger -## 配置说明 +### 配置说明 -### 1. 基础配置 +#### 基础配置 #### 应用程序配置 @@ -247,7 +301,7 @@ Redis 配置示例: } ``` -### 2. 认证配置 +### 认证配置 #### OpenIddict 配置 @@ -294,7 +348,7 @@ Redis 配置示例: } ``` -### 3. 功能开关配置 +### 功能开关配置 ```json { @@ -310,7 +364,7 @@ Redis 配置示例: } ``` -### 4. 日志配置 +### 日志配置 ```json { From 6d432838b25f3a27d9b8f57c3143d191b02f84fc Mon Sep 17 00:00:00 2001 From: feijie Date: Wed, 1 Jan 2025 22:53:21 +0800 Subject: [PATCH 29/29] =?UTF-8?q?=F0=9F=93=9D=20docs(startup-aio-readme):?= =?UTF-8?q?=20=E6=9B=B4=E6=96=B0=E5=AE=89=E8=A3=85=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=BE=AE=E6=9C=8D=E5=8A=A1=E5=92=8C?= =?UTF-8?q?=E5=8D=95=E4=BD=93=E5=BA=94=E7=94=A8=E6=A8=A1=E6=9D=BF=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/startup-aio-readme.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/startup-aio-readme.md b/docs/startup-aio-readme.md index bb0c4540d..d8c7ff4fb 100644 --- a/docs/startup-aio-readme.md +++ b/docs/startup-aio-readme.md @@ -34,10 +34,20 @@ - PostgreSQL - Redis -### 安装命令行工具 +### 安装模板 ```bash -dotnet tool install --global LINGYUN.Abp.Cli +# 安装微服务模板: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 ``` ### 创建项目