57 changed files with 4840 additions and 1 deletions
@ -0,0 +1,263 @@ |
|||||
|
<Project> |
||||
|
<Import Project="..\..\Directory.Packages.props" /> |
||||
|
<PropertyGroup> |
||||
|
<LYAbpPackageVersion>8.3.0</LYAbpPackageVersion> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageVersion Include="DistributedLock.Redis" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Elsa.Activities.Email" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Elsa.Activities.Http" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Elsa.Activities.UserTask" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Elsa.Activities.Temporal.Quartz" Version="$(LYAbpPackageVersion)" /> |
||||
|
<!--<PackageVersion Include="Elsa.Designer.Components.Web" Version="$(LYAbpPackageVersion)" />--> |
||||
|
<PackageVersion Include="Elsa.Webhooks.Api" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="OpenIddict.Validation.DataProtection" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="OpenIddict.Server.DataProtection" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.AspNetCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Enrichers.Environment" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Enrichers.Assembly" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Enrichers.Process" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Enrichers.Thread" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Settings.Configuration" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Sinks.Elasticsearch" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Serilog.Sinks.File" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Swashbuckle.AspNetCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Quartz.Serialization.Json" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.Account.Web.OpenIddict" Version="$(LYAbpPackageVersion)" /> |
||||
|
<!--<PackageVersion Include="Volo.Abp.Account.Web.IdentityServer" Version="$(LYAbpPackageVersion)" />--> |
||||
|
<PackageVersion Include="Volo.Abp.AspNetCore.Serilog" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.Autofac" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.Caching.StackExchangeRedis" Version="$(LYAbpPackageVersion)" /> |
||||
|
<!-- <PackageVersion Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="$(LYAbpPackageVersion)" />--> |
||||
|
<PackageVersion Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.FeatureManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.FeatureManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.PermissionManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.IdentityServer" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.PermissionManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.Identity.AspNetCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.Imaging.ImageSharp" Version="$(LYAbpPackageVersion)" /> |
||||
|
<!--<PackageVersion Include="Volo.Abp.IdentityServer.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" />--> |
||||
|
<PackageVersion Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="Volo.Abp.OpenIddict.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageVersion Include="LINGYUN.Abp.AuditLogging.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.AuditLogging" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Authentication.QQ" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Authentication.WeChat" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Authorization.OrganizationUnits" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Aliyun.SettingManagement" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Aliyun" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Tencent.QQ" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Tencent.SettingManagement" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Tencent" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.AspNetCore.HttpOverrides" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Data.DbMigrator" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Emailing" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis.Client" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation.Redis" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Features.LimitValidation" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Http.Client.Wrapper" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdGenerator" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.RealTime" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Wrapper" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Dynamic.Queryable.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Linq.Dynamic.Queryable" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Exporter.MiniExcel" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.Client" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Localization" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Localization.CultureMap" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Localization.Persistence" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Logging.Serilog.Elasticsearch" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Logging" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Serilog.Enrichers.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Serilog.Enrichers.UniqueId" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Sms.Aliyun" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.UI.Navigation" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenApi.Authorization" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MultiTenancy.Editions" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.WeChat" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.MiniProgram" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Handlers" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Official" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Official.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.SettingManagement" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.Handlers" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Work.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat.Work" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WeChat" Version="$(LYAbpPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Account.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Account.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Account.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Account.Templates" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Auditing.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Auditing.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Auditing.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.CachingManagement.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.CachingManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.CachingManagement.StackExchangeRedis" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.DataProtectionManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Demo.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Demo.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Demo.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.BlobStoring" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Emailing" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.IM" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Notifications" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Sms" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities.Webhooks" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Activities" Version="$(LYAbpPackageVersion)" /> |
||||
|
<!-- <PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql" Version="$(LYAbpPackageVersion)" />--> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.PostgreSql" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa.Server" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Elsa" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.FeatureManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Session" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.AspNetCore.Session" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.Notifications" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.OrganizaztionUnits" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.LinkUser" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.Portal" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.SmsValidator" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IdentityServer.WeChat.Work" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Identity.Session.AspNetCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.LocalizationManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.AspNetCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IM.SignalR" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.IM" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MessageService.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MessageService.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MessageService.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MessageService.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.MessageService.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling.Notifications" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.ExceptionHandling" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Common" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Core" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Emailing" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.SignalR" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Notifications.WeChat.Work" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.LinkUser" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Sms" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.Portal" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OpenIddict.WeChat.Work" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.FileSystem" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.Imaging" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.Minio" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.OssManagement.SettingManagement" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.PermissionManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.Settings.VueVbenAdmin" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Platform.Theme.VueVbenAdmin" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Saas.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Saas.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Saas.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Saas.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Saas.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Saas.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.SettingManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.SettingManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Abstractions" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Activities" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.EventBus" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Jobs" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Notifications" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks.Quartz" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.BackgroundTasks" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TaskManagement.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TaskManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TextTemplating.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TextTemplating.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.TextTemplating.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Webhooks.Core" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Webhooks.EventBus" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Webhooks.Identity" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Webhooks.Saas" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Application" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.Domain" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.WebhooksManagement.HttpApi" Version="$(LYAbpPackageVersion)" /> |
||||
|
<PackageVersion Include="LINGYUN.Abp.Webhooks" Version="$(LYAbpPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
</Project> |
||||
@ -0,0 +1,12 @@ |
|||||
|
{ |
||||
|
"version": 1, |
||||
|
"isRoot": true, |
||||
|
"tools": { |
||||
|
"dotnet-ef": { |
||||
|
"version": "7.0.3", |
||||
|
"commands": [ |
||||
|
"dotnet-ef" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
wwwroot |
||||
|
package*.json |
||||
@ -0,0 +1,89 @@ |
|||||
|
using Microsoft.AspNetCore.Authentication; |
||||
|
using Microsoft.AspNetCore.Authentication.Cookies; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System.Text.Encodings.Web; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Authentication; |
||||
|
|
||||
|
public class AbpCookieAuthenticationHandler : CookieAuthenticationHandler |
||||
|
{ |
||||
|
public AbpCookieAuthenticationHandler( |
||||
|
IOptionsMonitor<CookieAuthenticationOptions> options, |
||||
|
ILoggerFactory logger, |
||||
|
UrlEncoder encoder) : base(options, logger, encoder) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public AbpCookieAuthenticationHandler( |
||||
|
IOptionsMonitor<CookieAuthenticationOptions> options, |
||||
|
ILoggerFactory logger, |
||||
|
UrlEncoder encoder, |
||||
|
ISystemClock clock) : base(options, logger, encoder, clock) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected const string XRequestFromHeader = "X-Request-From"; |
||||
|
protected const string DontRedirectRequestFromHeader = "vben"; |
||||
|
protected override Task InitializeEventsAsync() |
||||
|
{ |
||||
|
var events = new CookieAuthenticationEvents |
||||
|
{ |
||||
|
OnRedirectToLogin = ctx => |
||||
|
{ |
||||
|
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal)) |
||||
|
{ |
||||
|
// ctx.Response.Headers.Location = ctx.RedirectUri;
|
||||
|
ctx.Response.StatusCode = 401; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ctx.Response.Redirect(ctx.RedirectUri); |
||||
|
} |
||||
|
return Task.CompletedTask; |
||||
|
}, |
||||
|
OnRedirectToAccessDenied = ctx => |
||||
|
{ |
||||
|
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal)) |
||||
|
{ |
||||
|
// ctx.Response.Headers.Location = ctx.RedirectUri;
|
||||
|
ctx.Response.StatusCode = 401; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ctx.Response.Redirect(ctx.RedirectUri); |
||||
|
} |
||||
|
return Task.CompletedTask; |
||||
|
}, |
||||
|
OnRedirectToLogout = ctx => |
||||
|
{ |
||||
|
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal)) |
||||
|
{ |
||||
|
// ctx.Response.Headers.Location = ctx.RedirectUri;
|
||||
|
ctx.Response.StatusCode = 401; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ctx.Response.Redirect(ctx.RedirectUri); |
||||
|
} |
||||
|
return Task.CompletedTask; |
||||
|
}, |
||||
|
OnRedirectToReturnUrl = ctx => |
||||
|
{ |
||||
|
if (string.Equals(ctx.Request.Headers[XRequestFromHeader], DontRedirectRequestFromHeader, StringComparison.Ordinal)) |
||||
|
{ |
||||
|
// ctx.Response.Headers.Location = ctx.RedirectUri;
|
||||
|
ctx.Response.StatusCode = 401; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ctx.Response.Redirect(ctx.RedirectUri); |
||||
|
} |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Events = events; |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.BackgroundJobs; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.BackgroundJobs; |
||||
|
|
||||
|
public class NotificationPublishJob : AsyncBackgroundJob<NotificationPublishJobArgs>, ITransientDependency |
||||
|
{ |
||||
|
protected AbpNotificationsPublishOptions Options { get; } |
||||
|
protected IServiceScopeFactory ServiceScopeFactory { get; } |
||||
|
protected INotificationDataSerializer NotificationDataSerializer { get; } |
||||
|
public NotificationPublishJob( |
||||
|
IOptions<AbpNotificationsPublishOptions> options, |
||||
|
IServiceScopeFactory serviceScopeFactory, |
||||
|
INotificationDataSerializer notificationDataSerializer) |
||||
|
{ |
||||
|
Options = options.Value; |
||||
|
ServiceScopeFactory = serviceScopeFactory; |
||||
|
NotificationDataSerializer = notificationDataSerializer; |
||||
|
} |
||||
|
|
||||
|
public override async Task ExecuteAsync(NotificationPublishJobArgs args) |
||||
|
{ |
||||
|
var providerType = Type.GetType(args.ProviderType); |
||||
|
using (var scope = ServiceScopeFactory.CreateScope()) |
||||
|
{ |
||||
|
if (scope.ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider) |
||||
|
{ |
||||
|
var store = scope.ServiceProvider.GetRequiredService<INotificationStore>(); |
||||
|
var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); |
||||
|
notification.Data = NotificationDataSerializer.Serialize(notification.Data); |
||||
|
|
||||
|
await publishProvider.PublishAsync(notification, args.UserIdentifiers); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using LINGYUN.Abp.Notifications; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.BackgroundJobs; |
||||
|
|
||||
|
public class NotificationPublishJobArgs |
||||
|
{ |
||||
|
public Guid? TenantId { get; set; } |
||||
|
public long NotificationId { get; set; } |
||||
|
public string ProviderType { get; set; } |
||||
|
public List<UserIdentifier> UserIdentifiers { get; set; } |
||||
|
public NotificationPublishJobArgs() |
||||
|
{ |
||||
|
UserIdentifiers = new List<UserIdentifier>(); |
||||
|
} |
||||
|
public NotificationPublishJobArgs(long id, string providerType, List<UserIdentifier> userIdentifiers, Guid? tenantId = null) |
||||
|
{ |
||||
|
NotificationId = id; |
||||
|
ProviderType = providerType; |
||||
|
UserIdentifiers = userIdentifiers; |
||||
|
TenantId = tenantId; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Controllers; |
||||
|
|
||||
|
public class HomeController : Controller |
||||
|
{ |
||||
|
public IActionResult Index() |
||||
|
{ |
||||
|
return Redirect("/swagger"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
using LINGYUN.Abp.SettingManagement; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Controllers; |
||||
|
|
||||
|
[ExposeServices( |
||||
|
typeof(SettingController), |
||||
|
typeof(SettingMergeController))] |
||||
|
public class SettingMergeController : SettingController |
||||
|
{ |
||||
|
private readonly SettingManagementMergeOptions _mergeOptions; |
||||
|
public SettingMergeController( |
||||
|
ISettingAppService settingAppService, |
||||
|
ISettingTestAppService settingTestAppService, |
||||
|
IOptions<SettingManagementMergeOptions> mergeOptions) |
||||
|
: base(settingAppService, settingTestAppService) |
||||
|
{ |
||||
|
_mergeOptions = mergeOptions.Value; |
||||
|
} |
||||
|
|
||||
|
[HttpGet] |
||||
|
[Route("by-current-tenant")] |
||||
|
public async override Task<SettingGroupResult> GetAllForCurrentTenantAsync() |
||||
|
{ |
||||
|
var result = new SettingGroupResult(); |
||||
|
var markTypeMap = new List<Type> |
||||
|
{ |
||||
|
typeof(SettingMergeController), |
||||
|
}; |
||||
|
foreach (var serviceType in _mergeOptions.GlobalSettingProviders |
||||
|
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) |
||||
|
{ |
||||
|
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IReadonlySettingAppService>(); |
||||
|
var currentResult = await settingService.GetAllForCurrentTenantAsync(); |
||||
|
foreach (var group in currentResult.Items) |
||||
|
{ |
||||
|
result.AddGroup(group); |
||||
|
} |
||||
|
markTypeMap.Add(serviceType); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
[HttpGet] |
||||
|
[Route("by-global")] |
||||
|
public async override Task<SettingGroupResult> GetAllForGlobalAsync() |
||||
|
{ |
||||
|
var result = new SettingGroupResult(); |
||||
|
var markTypeMap = new List<Type> |
||||
|
{ |
||||
|
typeof(SettingMergeController), |
||||
|
}; |
||||
|
foreach (var serviceType in _mergeOptions.GlobalSettingProviders |
||||
|
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) |
||||
|
{ |
||||
|
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IReadonlySettingAppService>(); |
||||
|
var currentResult = await settingService.GetAllForGlobalAsync(); |
||||
|
foreach (var group in currentResult.Items) |
||||
|
{ |
||||
|
result.AddGroup(group); |
||||
|
} |
||||
|
markTypeMap.Add(serviceType); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
using LINGYUN.Abp.SettingManagement; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Controllers; |
||||
|
|
||||
|
[ExposeServices( |
||||
|
typeof(UserSettingController), |
||||
|
typeof(UserSettingMergeController))] |
||||
|
public class UserSettingMergeController : UserSettingController |
||||
|
{ |
||||
|
private readonly SettingManagementMergeOptions _mergeOptions; |
||||
|
public UserSettingMergeController( |
||||
|
IUserSettingAppService service, |
||||
|
IOptions<SettingManagementMergeOptions> mergeOptions) |
||||
|
: base(service) |
||||
|
{ |
||||
|
_mergeOptions = mergeOptions.Value; |
||||
|
} |
||||
|
|
||||
|
[HttpGet] |
||||
|
[Route("by-current-user")] |
||||
|
public async override Task<SettingGroupResult> GetAllForCurrentUserAsync() |
||||
|
{ |
||||
|
var result = new SettingGroupResult(); |
||||
|
var markTypeMap = new List<Type> |
||||
|
{ |
||||
|
typeof(UserSettingMergeController), |
||||
|
}; |
||||
|
foreach (var serviceType in _mergeOptions.UserSettingProviders |
||||
|
.Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) |
||||
|
{ |
||||
|
var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As<IUserSettingAppService>(); |
||||
|
var currentResult = await settingService.GetAllForCurrentUserAsync(); |
||||
|
foreach (var group in currentResult.Items) |
||||
|
{ |
||||
|
result.AddGroup(group); |
||||
|
} |
||||
|
markTypeMap.Add(serviceType); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0 |
||||
|
LABEL maintainer="colin.in@foxmail.com" |
||||
|
WORKDIR /app |
||||
|
|
||||
|
COPY . /app |
||||
|
|
||||
|
#东8区 |
||||
|
ENV TZ=Asia/Shanghai |
||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone |
||||
|
|
||||
|
EXPOSE 80/tcp |
||||
|
VOLUME [ "./app/blobs" ] |
||||
|
VOLUME [ "./app/Logs" ] |
||||
|
VOLUME [ "./app/Modules" ] |
||||
|
|
||||
|
RUN apt update |
||||
|
RUN apt install wget -y |
||||
|
|
||||
|
ENTRYPOINT ["dotnet", "LY.MicroService.Applications.Single.dll"] |
||||
@ -0,0 +1,59 @@ |
|||||
|
using LINGYUN.Abp.IM; |
||||
|
using LINGYUN.Abp.IM.Messages; |
||||
|
using LINGYUN.Abp.RealTime; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Distributed |
||||
|
{ |
||||
|
public class ChatMessageEventHandler : IDistributedEventHandler<RealTimeEto<ChatMessage>>, ITransientDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
|
||||
|
/// </summary>
|
||||
|
public ILogger<ChatMessageEventHandler> Logger { get; set; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="AbpIMOptions"/>.
|
||||
|
/// </summary>
|
||||
|
protected AbpIMOptions Options { get; } |
||||
|
|
||||
|
protected IMessageStore MessageStore { get; } |
||||
|
protected IMessageBlocker MessageBlocker { get; } |
||||
|
protected IMessageSenderProviderManager MessageSenderProviderManager { get; } |
||||
|
|
||||
|
public ChatMessageEventHandler( |
||||
|
IOptions<AbpIMOptions> options, |
||||
|
IMessageStore messageStore, |
||||
|
IMessageBlocker messageBlocker, |
||||
|
IMessageSenderProviderManager messageSenderProviderManager) |
||||
|
{ |
||||
|
Options = options.Value; |
||||
|
MessageStore = messageStore; |
||||
|
MessageBlocker = messageBlocker; |
||||
|
MessageSenderProviderManager = messageSenderProviderManager; |
||||
|
|
||||
|
Logger = NullLogger<ChatMessageEventHandler>.Instance; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(RealTimeEto<ChatMessage> eventData) |
||||
|
{ |
||||
|
Logger.LogDebug($"Persistent chat message."); |
||||
|
|
||||
|
var message = eventData.Data; |
||||
|
// 消息拦截
|
||||
|
// 扩展敏感词汇过滤
|
||||
|
await MessageBlocker.InterceptAsync(message); |
||||
|
|
||||
|
await MessageStore.StoreMessageAsync(message); |
||||
|
|
||||
|
// 发送消息
|
||||
|
foreach (var provider in MessageSenderProviderManager.Providers) |
||||
|
{ |
||||
|
Logger.LogDebug($"Sending message with provider {provider.Name}"); |
||||
|
await provider.SendMessageAsync(message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,470 @@ |
|||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using LY.AIO.Applications.Single.BackgroundJobs; |
||||
|
using LY.AIO.Applications.Single.MultiTenancy; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System.Globalization; |
||||
|
using Volo.Abp.BackgroundJobs; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.Json; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.TextTemplating; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Distributed |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 订阅通知发布事件,统一发布消息
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 作用在于SignalR客户端只会与一台服务器建立连接,
|
||||
|
/// 只有启用了SignlR服务端的才能真正将消息发布到客户端
|
||||
|
/// </remarks>
|
||||
|
public class NotificationEventHandler : |
||||
|
IDistributedEventHandler<NotificationEto<NotificationData>>, |
||||
|
IDistributedEventHandler<NotificationEto<NotificationTemplate>>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
|
||||
|
/// </summary>
|
||||
|
public ILogger<NotificationEventHandler> Logger { get; set; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="AbpNotificationsPublishOptions"/>.
|
||||
|
/// </summary>
|
||||
|
protected AbpNotificationsPublishOptions Options { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="ICurrentTenant"/>.
|
||||
|
/// </summary>
|
||||
|
protected ICurrentTenant CurrentTenant { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="ITenantConfigurationCache"/>.
|
||||
|
/// </summary>
|
||||
|
protected ITenantConfigurationCache TenantConfigurationCache { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="IJsonSerializer"/>.
|
||||
|
/// </summary>
|
||||
|
protected IJsonSerializer JsonSerializer { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="IBackgroundJobManager"/>.
|
||||
|
/// </summary>
|
||||
|
protected IBackgroundJobManager BackgroundJobManager { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="ITemplateRenderer"/>.
|
||||
|
/// </summary>
|
||||
|
protected ITemplateRenderer TemplateRenderer { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="INotificationStore"/>.
|
||||
|
/// </summary>
|
||||
|
protected INotificationStore NotificationStore { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="IStringLocalizerFactory"/>.
|
||||
|
/// </summary>
|
||||
|
protected IStringLocalizerFactory StringLocalizerFactory { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="INotificationDataSerializer"/>.
|
||||
|
/// </summary>
|
||||
|
protected INotificationDataSerializer NotificationDataSerializer { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="INotificationDefinitionManager"/>.
|
||||
|
/// </summary>
|
||||
|
protected INotificationDefinitionManager NotificationDefinitionManager { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="INotificationSubscriptionManager"/>.
|
||||
|
/// </summary>
|
||||
|
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } |
||||
|
/// <summary>
|
||||
|
/// Reference to <see cref="INotificationPublishProviderManager"/>.
|
||||
|
/// </summary>
|
||||
|
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="NotificationEventHandler"/> class.
|
||||
|
/// </summary>
|
||||
|
public NotificationEventHandler( |
||||
|
ICurrentTenant currentTenant, |
||||
|
ITenantConfigurationCache tenantConfigurationCache, |
||||
|
IJsonSerializer jsonSerializer, |
||||
|
ITemplateRenderer templateRenderer, |
||||
|
IBackgroundJobManager backgroundJobManager, |
||||
|
IStringLocalizerFactory stringLocalizerFactory, |
||||
|
IOptions<AbpNotificationsPublishOptions> options, |
||||
|
INotificationStore notificationStore, |
||||
|
INotificationDataSerializer notificationDataSerializer, |
||||
|
INotificationDefinitionManager notificationDefinitionManager, |
||||
|
INotificationSubscriptionManager notificationSubscriptionManager, |
||||
|
INotificationPublishProviderManager notificationPublishProviderManager) |
||||
|
{ |
||||
|
Options = options.Value; |
||||
|
TenantConfigurationCache = tenantConfigurationCache; |
||||
|
CurrentTenant = currentTenant; |
||||
|
JsonSerializer = jsonSerializer; |
||||
|
TemplateRenderer = templateRenderer; |
||||
|
BackgroundJobManager = backgroundJobManager; |
||||
|
StringLocalizerFactory = stringLocalizerFactory; |
||||
|
NotificationStore = notificationStore; |
||||
|
NotificationDataSerializer = notificationDataSerializer; |
||||
|
NotificationDefinitionManager = notificationDefinitionManager; |
||||
|
NotificationSubscriptionManager = notificationSubscriptionManager; |
||||
|
NotificationPublishProviderManager = notificationPublishProviderManager; |
||||
|
|
||||
|
Logger = NullLogger<NotificationEventHandler>.Instance; |
||||
|
} |
||||
|
|
||||
|
[UnitOfWork] |
||||
|
public async virtual Task HandleEventAsync(NotificationEto<NotificationTemplate> eventData) |
||||
|
{ |
||||
|
var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name); |
||||
|
if (notification == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var culture = eventData.Data.Culture; |
||||
|
if (culture.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
culture = CultureInfo.CurrentCulture.Name; |
||||
|
} |
||||
|
using (CultureHelper.Use(culture, culture)) |
||||
|
{ |
||||
|
if (notification.NotificationType == NotificationType.System) |
||||
|
{ |
||||
|
using (CurrentTenant.Change(null)) |
||||
|
{ |
||||
|
await SendToTenantAsync(null, notification, eventData); |
||||
|
|
||||
|
var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync(); |
||||
|
|
||||
|
foreach (var activeTenant in allActiveTenants) |
||||
|
{ |
||||
|
await SendToTenantAsync(activeTenant.Id, notification, eventData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
await SendToTenantAsync(eventData.TenantId, notification, eventData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[UnitOfWork] |
||||
|
public async virtual Task HandleEventAsync(NotificationEto<NotificationData> eventData) |
||||
|
{ |
||||
|
var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name); |
||||
|
if (notification == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (notification.NotificationType == NotificationType.System) |
||||
|
{ |
||||
|
using (CurrentTenant.Change(null)) |
||||
|
{ |
||||
|
await SendToTenantAsync(null, notification, eventData); |
||||
|
|
||||
|
var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync(); |
||||
|
|
||||
|
foreach (var activeTenant in allActiveTenants) |
||||
|
{ |
||||
|
await SendToTenantAsync(activeTenant.Id, notification, eventData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
await SendToTenantAsync(eventData.TenantId, notification, eventData); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task SendToTenantAsync( |
||||
|
Guid? tenantId, |
||||
|
NotificationDefinition notification, |
||||
|
NotificationEto<NotificationTemplate> eventData) |
||||
|
{ |
||||
|
using (CurrentTenant.Change(tenantId)) |
||||
|
{ |
||||
|
var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers); |
||||
|
|
||||
|
// 过滤用户指定提供者
|
||||
|
if (eventData.UseProviders.Any()) |
||||
|
{ |
||||
|
providers = providers.Where(p => eventData.UseProviders.Contains(p.Name)); |
||||
|
} |
||||
|
else if (notification.Providers.Any()) |
||||
|
{ |
||||
|
providers = providers.Where(p => notification.Providers.Contains(p.Name)); |
||||
|
} |
||||
|
|
||||
|
var notificationInfo = new NotificationInfo |
||||
|
{ |
||||
|
Name = notification.Name, |
||||
|
TenantId = tenantId, |
||||
|
Severity = eventData.Severity, |
||||
|
Type = notification.NotificationType, |
||||
|
ContentType = notification.ContentType, |
||||
|
CreationTime = eventData.CreationTime, |
||||
|
Lifetime = notification.NotificationLifetime, |
||||
|
}; |
||||
|
notificationInfo.SetId(eventData.Id); |
||||
|
|
||||
|
var title = notification.DisplayName.Localize(StringLocalizerFactory); |
||||
|
var message = ""; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
// 由于模板通知受租户影响, 格式化失败的消息将被丢弃.
|
||||
|
message = await TemplateRenderer.RenderAsync( |
||||
|
templateName: eventData.Data.Name, |
||||
|
model: eventData.Data.ExtraProperties, |
||||
|
cultureName: eventData.Data.Culture, |
||||
|
globalContext: new Dictionary<string, object> |
||||
|
{ |
||||
|
// 模板不支持 $ 字符, 改为普通关键字
|
||||
|
{ NotificationKeywords.Name, notification.Name }, |
||||
|
{ NotificationKeywords.FormUser, eventData.Data.FormUser }, |
||||
|
{ NotificationKeywords.Id, eventData.Id }, |
||||
|
{ NotificationKeywords.Title, title.ToString() }, |
||||
|
{ NotificationKeywords.CreationTime, eventData.CreationTime.ToString(Options.DateTimeFormat) }, |
||||
|
}); |
||||
|
} |
||||
|
catch(Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning("Formatting template notification failed, message will be discarded, cause :{message}", ex.Message); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var notificationData = new NotificationData(); |
||||
|
notificationData.WriteStandardData( |
||||
|
title: title.ToString(), |
||||
|
message: message, |
||||
|
createTime: eventData.CreationTime, |
||||
|
formUser: eventData.Data.FormUser); |
||||
|
notificationData.ExtraProperties.AddIfNotContains(eventData.Data.ExtraProperties); |
||||
|
|
||||
|
notificationInfo.Data = notificationData; |
||||
|
|
||||
|
var subscriptionUsers = await GerSubscriptionUsersAsync( |
||||
|
notificationInfo.Name, |
||||
|
eventData.Users, |
||||
|
tenantId); |
||||
|
|
||||
|
await PersistentNotificationAsync( |
||||
|
notificationInfo, |
||||
|
subscriptionUsers, |
||||
|
providers); |
||||
|
|
||||
|
if (subscriptionUsers.Any()) |
||||
|
{ |
||||
|
// 发布通知
|
||||
|
foreach (var provider in providers) |
||||
|
{ |
||||
|
await PublishToSubscriberAsync(provider, notificationInfo, subscriptionUsers); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task SendToTenantAsync( |
||||
|
Guid? tenantId, |
||||
|
NotificationDefinition notification, |
||||
|
NotificationEto<NotificationData> eventData) |
||||
|
{ |
||||
|
using (CurrentTenant.Change(tenantId)) |
||||
|
{ |
||||
|
var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers); |
||||
|
|
||||
|
// 过滤用户指定提供者
|
||||
|
if (eventData.UseProviders.Any()) |
||||
|
{ |
||||
|
providers = providers.Where(p => eventData.UseProviders.Contains(p.Name)); |
||||
|
} |
||||
|
else if (notification.Providers.Any()) |
||||
|
{ |
||||
|
providers = providers.Where(p => notification.Providers.Contains(p.Name)); |
||||
|
} |
||||
|
|
||||
|
var notificationInfo = new NotificationInfo |
||||
|
{ |
||||
|
Name = notification.Name, |
||||
|
CreationTime = eventData.CreationTime, |
||||
|
Data = eventData.Data, |
||||
|
Severity = eventData.Severity, |
||||
|
Lifetime = notification.NotificationLifetime, |
||||
|
TenantId = tenantId, |
||||
|
Type = notification.NotificationType, |
||||
|
ContentType = notification.ContentType, |
||||
|
}; |
||||
|
notificationInfo.SetId(eventData.Id); |
||||
|
|
||||
|
notificationInfo.Data = NotificationDataSerializer.Serialize(notificationInfo.Data); |
||||
|
|
||||
|
// 获取用户订阅
|
||||
|
var subscriptionUsers = await GerSubscriptionUsersAsync( |
||||
|
notificationInfo.Name, |
||||
|
eventData.Users, |
||||
|
tenantId); |
||||
|
|
||||
|
// 持久化通知
|
||||
|
await PersistentNotificationAsync( |
||||
|
notificationInfo, |
||||
|
subscriptionUsers, |
||||
|
providers); |
||||
|
|
||||
|
if (subscriptionUsers.Any()) |
||||
|
{ |
||||
|
// 发布订阅通知
|
||||
|
foreach (var provider in providers) |
||||
|
{ |
||||
|
await PublishToSubscriberAsync(provider, notificationInfo, subscriptionUsers); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 获取用户订阅列表
|
||||
|
/// </summary>
|
||||
|
/// <param name="notificationName">通知名称</param>
|
||||
|
/// <param name="sendToUsers">接收用户列表</param>
|
||||
|
/// <param name="tenantId">租户标识</param>
|
||||
|
/// <returns>用户订阅列表</returns>
|
||||
|
protected async Task<IEnumerable<UserIdentifier>> GerSubscriptionUsersAsync( |
||||
|
string notificationName, |
||||
|
IEnumerable<UserIdentifier> sendToUsers, |
||||
|
Guid? tenantId = null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
// 获取用户订阅列表
|
||||
|
var userSubscriptions = await NotificationSubscriptionManager.GetUsersSubscriptionsAsync( |
||||
|
tenantId, |
||||
|
notificationName, |
||||
|
sendToUsers); |
||||
|
|
||||
|
return userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName)); |
||||
|
} |
||||
|
catch(Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning("Failed to get user subscription, message will not be received by the user, reason: {message}", ex.Message); |
||||
|
} |
||||
|
|
||||
|
return new List<UserIdentifier>(); |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 持久化通知并返回订阅用户列表
|
||||
|
/// </summary>
|
||||
|
/// <param name="notificationInfo">通知实体</param>
|
||||
|
/// <param name="subscriptionUsers">订阅用户列表</param>
|
||||
|
/// <param name="sendToProviders">通知发送提供者</param>
|
||||
|
/// <returns>返回订阅者列表</returns>
|
||||
|
protected async Task PersistentNotificationAsync( |
||||
|
NotificationInfo notificationInfo, |
||||
|
IEnumerable<UserIdentifier> subscriptionUsers, |
||||
|
IEnumerable<INotificationPublishProvider> sendToProviders) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
// 持久化通知
|
||||
|
await NotificationStore.InsertNotificationAsync(notificationInfo); |
||||
|
|
||||
|
if (!subscriptionUsers.Any()) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 持久化用户通知
|
||||
|
await NotificationStore.InsertUserNotificationsAsync(notificationInfo, subscriptionUsers.Select(u => u.UserId)); |
||||
|
|
||||
|
if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne) |
||||
|
{ |
||||
|
// 一次性通知取消用户订阅
|
||||
|
await NotificationStore.DeleteUserSubscriptionAsync( |
||||
|
notificationInfo.TenantId, |
||||
|
subscriptionUsers, |
||||
|
notificationInfo.Name); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning("Failed to persistent notification failed, reason: {message}", ex.Message); |
||||
|
|
||||
|
foreach (var provider in sendToProviders) |
||||
|
{ |
||||
|
// 处理持久化失败进入后台队列
|
||||
|
await ProcessingFailedToQueueAsync(provider, notificationInfo, subscriptionUsers); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 发布订阅者通知
|
||||
|
/// </summary>
|
||||
|
/// <param name="provider">通知发布者</param>
|
||||
|
/// <param name="notificationInfo">通知信息</param>
|
||||
|
/// <param name="subscriptionUserIdentifiers">订阅用户列表</param>
|
||||
|
/// <returns></returns>
|
||||
|
protected async Task PublishToSubscriberAsync( |
||||
|
INotificationPublishProvider provider, |
||||
|
NotificationInfo notificationInfo, |
||||
|
IEnumerable<UserIdentifier> subscriptionUsers) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
Logger.LogDebug($"Sending notification with provider {provider.Name}"); |
||||
|
|
||||
|
// 2024-10-10: 框架层面应该取消通知数据转换,而是交给提供商来实现
|
||||
|
//var notifacationDataMapping = Options.NotificationDataMappings
|
||||
|
// .GetMapItemOrDefault(provider.Name, notificationInfo.Name);
|
||||
|
//if (notifacationDataMapping != null)
|
||||
|
//{
|
||||
|
// notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
|
||||
|
//}
|
||||
|
|
||||
|
// 发布
|
||||
|
await provider.PublishAsync(notificationInfo, subscriptionUsers); |
||||
|
|
||||
|
Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful"); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning($"Send notification error with provider {provider.Name}"); |
||||
|
Logger.LogWarning($"Error message:{ex.Message}"); |
||||
|
Logger.LogDebug($"Failed to send notification {notificationInfo.Name}. Try to push notification to background job"); |
||||
|
// 发送失败的消息进入后台队列
|
||||
|
await ProcessingFailedToQueueAsync(provider, notificationInfo, subscriptionUsers); |
||||
|
} |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 处理失败的消息进入后台队列
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 注: 如果入队失败,消息将被丢弃.
|
||||
|
/// </remarks>
|
||||
|
/// <param name="provider"></param>
|
||||
|
/// <param name="notificationInfo"></param>
|
||||
|
/// <param name="subscriptionUsers"></param>
|
||||
|
/// <returns></returns>
|
||||
|
protected async Task ProcessingFailedToQueueAsync( |
||||
|
INotificationPublishProvider provider, |
||||
|
NotificationInfo notificationInfo, |
||||
|
IEnumerable<UserIdentifier> subscriptionUsers) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
// 发送失败的消息进入后台队列
|
||||
|
await BackgroundJobManager.EnqueueAsync( |
||||
|
new NotificationPublishJobArgs( |
||||
|
notificationInfo.GetId(), |
||||
|
provider.GetType().AssemblyQualifiedName, |
||||
|
subscriptionUsers.ToList(), |
||||
|
notificationInfo.TenantId)); |
||||
|
} |
||||
|
catch(Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning("Failed to push to background job, notification will be discarded, error cause: {message}", ex.Message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
using LINGYUN.Abp.Saas.Tenants; |
||||
|
using LY.AIO.Applications.Single.MultiTenancy; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Domain.Entities.Events.Distributed; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Distributed |
||||
|
{ |
||||
|
public class TenantSynchronizer : |
||||
|
IDistributedEventHandler<EntityCreatedEto<TenantEto>>, |
||||
|
IDistributedEventHandler<EntityUpdatedEto<TenantEto>>, |
||||
|
IDistributedEventHandler<EntityDeletedEto<TenantEto>>, |
||||
|
IDistributedEventHandler<TenantConnectionStringUpdatedEto>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
protected IDataSeeder DataSeeder { get; } |
||||
|
protected ITenantConfigurationCache TenantConfigurationCache { get; } |
||||
|
|
||||
|
public TenantSynchronizer( |
||||
|
IDataSeeder dataSeeder, |
||||
|
ITenantConfigurationCache tenantConfigurationCache) |
||||
|
{ |
||||
|
DataSeeder = dataSeeder; |
||||
|
TenantConfigurationCache = tenantConfigurationCache; |
||||
|
} |
||||
|
|
||||
|
[UnitOfWork] |
||||
|
public async virtual Task HandleEventAsync(EntityCreatedEto<TenantEto> eventData) |
||||
|
{ |
||||
|
await TenantConfigurationCache.RefreshAsync(); |
||||
|
|
||||
|
await DataSeeder.SeedAsync(eventData.Entity.Id); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(EntityUpdatedEto<TenantEto> eventData) |
||||
|
{ |
||||
|
await TenantConfigurationCache.RefreshAsync(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData) |
||||
|
{ |
||||
|
await TenantConfigurationCache.RefreshAsync(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) |
||||
|
{ |
||||
|
await TenantConfigurationCache.RefreshAsync(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Domain.Entities.Events; |
||||
|
using Volo.Abp.Domain.Entities.Events.Distributed; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.EventBus.Local; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Distributed |
||||
|
{ |
||||
|
public class UserCreateEventHandler : IDistributedEventHandler<EntityCreatedEto<UserEto>>, ITransientDependency |
||||
|
{ |
||||
|
private readonly ILocalEventBus _localEventBus; |
||||
|
public UserCreateEventHandler( |
||||
|
ILocalEventBus localEventBus) |
||||
|
{ |
||||
|
_localEventBus = localEventBus; |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 接收添加用户事件,发布本地事件
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventData"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public async Task HandleEventAsync(EntityCreatedEto<UserEto> eventData) |
||||
|
{ |
||||
|
var localUserCreateEventData = new EntityCreatedEventData<UserEto>(eventData.Entity); |
||||
|
|
||||
|
await _localEventBus.PublishAsync(localUserCreateEventData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
using LINGYUN.Abp.Webhooks; |
||||
|
using LINGYUN.Abp.Webhooks.EventBus; |
||||
|
using Volo.Abp.BackgroundJobs; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Distributed; |
||||
|
|
||||
|
public class WebhooksEventHandler : |
||||
|
IDistributedEventHandler<WebhooksEventData>, |
||||
|
ITransientDependency |
||||
|
{ |
||||
|
public IWebhookEventStore WebhookEventStore { get; set; } |
||||
|
|
||||
|
private readonly ICurrentTenant _currentTenant; |
||||
|
private readonly IBackgroundJobManager _backgroundJobManager; |
||||
|
private readonly IWebhookSubscriptionManager _webhookSubscriptionManager; |
||||
|
|
||||
|
public WebhooksEventHandler( |
||||
|
IWebhookSubscriptionManager webhookSubscriptionManager, |
||||
|
ICurrentTenant currentTenant, |
||||
|
IBackgroundJobManager backgroundJobManager) |
||||
|
{ |
||||
|
_currentTenant = currentTenant; |
||||
|
_backgroundJobManager = backgroundJobManager; |
||||
|
_webhookSubscriptionManager = webhookSubscriptionManager; |
||||
|
|
||||
|
WebhookEventStore = NullWebhookEventStore.Instance; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task HandleEventAsync(WebhooksEventData eventData) |
||||
|
{ |
||||
|
var subscriptions = await _webhookSubscriptionManager |
||||
|
.GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync( |
||||
|
eventData.TenantIds, |
||||
|
eventData.WebhookName); |
||||
|
|
||||
|
await PublishAsync(eventData.WebhookName, eventData.Data, subscriptions, eventData.SendExactSameData, eventData.Headers); |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task PublishAsync( |
||||
|
string webhookName, |
||||
|
string data, |
||||
|
List<WebhookSubscriptionInfo> webhookSubscriptions, |
||||
|
bool sendExactSameData = false, |
||||
|
WebhookHeader headers = null) |
||||
|
{ |
||||
|
if (webhookSubscriptions.IsNullOrEmpty()) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var subscriptionsGroupedByTenant = webhookSubscriptions.GroupBy(x => x.TenantId); |
||||
|
|
||||
|
foreach (var subscriptionGroupedByTenant in subscriptionsGroupedByTenant) |
||||
|
{ |
||||
|
var webhookInfo = await SaveAndGetWebhookAsync(subscriptionGroupedByTenant.Key, webhookName, data); |
||||
|
|
||||
|
foreach (var webhookSubscription in subscriptionGroupedByTenant) |
||||
|
{ |
||||
|
var headersToSend = webhookSubscription.Headers; |
||||
|
if (headers != null) |
||||
|
{ |
||||
|
if (headers.UseOnlyGivenHeaders)//do not use the headers defined in subscription
|
||||
|
{ |
||||
|
headersToSend = headers.Headers; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//use the headers defined in subscription. If additional headers has same header, use additional headers value.
|
||||
|
foreach (var additionalHeader in headers.Headers) |
||||
|
{ |
||||
|
headersToSend[additionalHeader.Key] = additionalHeader.Value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
await _backgroundJobManager.EnqueueAsync(new WebhookSenderArgs |
||||
|
{ |
||||
|
TenantId = webhookSubscription.TenantId, |
||||
|
WebhookEventId = webhookInfo.Id, |
||||
|
Data = webhookInfo.Data, |
||||
|
WebhookName = webhookInfo.WebhookName, |
||||
|
WebhookSubscriptionId = webhookSubscription.Id, |
||||
|
Headers = headersToSend, |
||||
|
Secret = webhookSubscription.Secret, |
||||
|
WebhookUri = webhookSubscription.WebhookUri, |
||||
|
SendExactSameData = sendExactSameData |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task<WebhookEvent> SaveAndGetWebhookAsync( |
||||
|
Guid? tenantId, |
||||
|
string webhookName, |
||||
|
string data) |
||||
|
{ |
||||
|
var webhookInfo = new WebhookEvent |
||||
|
{ |
||||
|
WebhookName = webhookName, |
||||
|
Data = data, |
||||
|
TenantId = tenantId |
||||
|
}; |
||||
|
|
||||
|
var webhookId = await WebhookEventStore.InsertAndGetIdAsync(webhookInfo); |
||||
|
webhookInfo.Id = webhookId; |
||||
|
|
||||
|
return webhookInfo; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using LINGYUN.Abp.MessageService.Chat; |
||||
|
using LINGYUN.Abp.MessageService.Notifications; |
||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Domain.Entities.Events; |
||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.Uow; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Local |
||||
|
{ |
||||
|
public class UserCreateJoinIMEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency |
||||
|
{ |
||||
|
private readonly IChatDataSeeder _chatDataSeeder; |
||||
|
private readonly INotificationSubscriptionManager _notificationSubscriptionManager; |
||||
|
public UserCreateJoinIMEventHandler( |
||||
|
IChatDataSeeder chatDataSeeder, |
||||
|
INotificationSubscriptionManager notificationSubscriptionManager) |
||||
|
{ |
||||
|
_chatDataSeeder = chatDataSeeder; |
||||
|
_notificationSubscriptionManager = notificationSubscriptionManager; |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 接收添加用户事件,初始化IM用户种子
|
||||
|
/// </summary>
|
||||
|
/// <param name="eventData"></param>
|
||||
|
/// <returns></returns>
|
||||
|
[UnitOfWork] |
||||
|
public async virtual Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData) |
||||
|
{ |
||||
|
await SeedChatDataAsync(eventData.Entity); |
||||
|
|
||||
|
await SeedUserSubscriptionNotifiersAsync(eventData.Entity); |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task SeedChatDataAsync(IUserData user) |
||||
|
{ |
||||
|
await _chatDataSeeder.SeedAsync(user); |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task SeedUserSubscriptionNotifiersAsync(IUserData user) |
||||
|
{ |
||||
|
var userIdentifier = new UserIdentifier(user.Id, user.UserName); |
||||
|
|
||||
|
await _notificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
user.TenantId, |
||||
|
userIdentifier, |
||||
|
MessageServiceNotificationNames.IM.FriendValidation); |
||||
|
|
||||
|
await _notificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
user.TenantId, |
||||
|
userIdentifier, |
||||
|
MessageServiceNotificationNames.IM.NewFriend); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Domain.Entities.Events; |
||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.EventBus.Local |
||||
|
{ |
||||
|
public class UserCreateSendWelcomeEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency |
||||
|
{ |
||||
|
private readonly INotificationSender _notificationSender; |
||||
|
private readonly INotificationSubscriptionManager _notificationSubscriptionManager; |
||||
|
public UserCreateSendWelcomeEventHandler( |
||||
|
INotificationSender notificationSender, |
||||
|
INotificationSubscriptionManager notificationSubscriptionManager |
||||
|
) |
||||
|
{ |
||||
|
_notificationSender = notificationSender; |
||||
|
_notificationSubscriptionManager = notificationSubscriptionManager; |
||||
|
} |
||||
|
|
||||
|
public async Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData) |
||||
|
{ |
||||
|
var userIdentifer = new UserIdentifier(eventData.Entity.Id, eventData.Entity.UserName); |
||||
|
// 订阅用户欢迎消息
|
||||
|
await SubscribeInternalNotifers(userIdentifer, eventData.Entity.TenantId); |
||||
|
|
||||
|
await _notificationSender.SendNofiterAsync( |
||||
|
UserNotificationNames.WelcomeToApplication, |
||||
|
new NotificationTemplate( |
||||
|
UserNotificationNames.WelcomeToApplication, |
||||
|
formUser: eventData.Entity.UserName, |
||||
|
data: new Dictionary<string, object> |
||||
|
{ |
||||
|
{ "name", eventData.Entity.UserName }, |
||||
|
}), |
||||
|
userIdentifer, |
||||
|
eventData.Entity.TenantId, |
||||
|
NotificationSeverity.Info); |
||||
|
} |
||||
|
|
||||
|
private async Task SubscribeInternalNotifers(UserIdentifier userIdentifer, Guid? tenantId = null) |
||||
|
{ |
||||
|
// 订阅内置通知
|
||||
|
await _notificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
tenantId, |
||||
|
userIdentifer, |
||||
|
DefaultNotifications.SystemNotice); |
||||
|
await _notificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
tenantId, |
||||
|
userIdentifer, |
||||
|
DefaultNotifications.OnsideNotice); |
||||
|
await _notificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
tenantId, |
||||
|
userIdentifer, |
||||
|
DefaultNotifications.ActivityNotice); |
||||
|
|
||||
|
// 订阅用户欢迎消息
|
||||
|
await _notificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
tenantId, |
||||
|
userIdentifer, |
||||
|
UserNotificationNames.WelcomeToApplication); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using LINGYUN.Abp.Identity; |
||||
|
using IdentityServer4.Models; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.IdentityResources; |
||||
|
|
||||
|
public class CustomIdentityResources |
||||
|
{ |
||||
|
public class AvatarUrl : IdentityResource |
||||
|
{ |
||||
|
public AvatarUrl() |
||||
|
{ |
||||
|
Name = IdentityConsts.ClaimType.Avatar.Name; |
||||
|
DisplayName = IdentityConsts.ClaimType.Avatar.DisplayName; |
||||
|
Description = IdentityConsts.ClaimType.Avatar.Description; |
||||
|
Emphasize = true; |
||||
|
UserClaims = new string[] { IdentityConsts.ClaimType.Avatar.Name }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,272 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.secrets.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net8.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<RootNamespace>LY.AIO.Applications.Single</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="DistributedLock.Redis" /> |
||||
|
<PackageReference Include="Elsa.Activities.Email" /> |
||||
|
<PackageReference Include="Elsa.Activities.Http" /> |
||||
|
<PackageReference Include="Elsa.Activities.UserTask" /> |
||||
|
<PackageReference Include="Elsa.Activities.Temporal.Quartz" /> |
||||
|
<!--<PackageReference Include="Elsa.Designer.Components.Web" />--> |
||||
|
<PackageReference Include="Elsa.Webhooks.Api" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" /> |
||||
|
<PackageReference Include="OpenIddict.Validation.DataProtection" /> |
||||
|
<PackageReference Include="OpenIddict.Server.DataProtection" /> |
||||
|
<PackageReference Include="Serilog.AspNetCore" /> |
||||
|
<PackageReference Include="Serilog.Enrichers.Environment" /> |
||||
|
<PackageReference Include="Serilog.Enrichers.Assembly" /> |
||||
|
<PackageReference Include="Serilog.Enrichers.Process" /> |
||||
|
<PackageReference Include="Serilog.Enrichers.Thread" /> |
||||
|
<PackageReference Include="Serilog.Settings.Configuration" /> |
||||
|
<PackageReference Include="Serilog.Sinks.Elasticsearch" /> |
||||
|
<PackageReference Include="Serilog.Sinks.File" /> |
||||
|
<PackageReference Include="Swashbuckle.AspNetCore" /> |
||||
|
<PackageReference Include="Quartz.Serialization.Json" /> |
||||
|
<PackageReference Include="Volo.Abp.Account.Web.OpenIddict" /> |
||||
|
<!--<PackageReference Include="Volo.Abp.Account.Web.IdentityServer" />--> |
||||
|
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" /> |
||||
|
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" /> |
||||
|
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" /> |
||||
|
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" /> |
||||
|
<PackageReference Include="Volo.Abp.Autofac" /> |
||||
|
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" /> |
||||
|
<!-- <PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" />--> |
||||
|
<PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql" /> |
||||
|
<PackageReference Include="Volo.Abp.FeatureManagement.Application" /> |
||||
|
<PackageReference Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="Volo.Abp.FeatureManagement.HttpApi" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.Application" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.IdentityServer" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi" /> |
||||
|
<PackageReference Include="Volo.Abp.Identity.AspNetCore" /> |
||||
|
<PackageReference Include="Volo.Abp.Imaging.ImageSharp" /> |
||||
|
<!--<PackageReference Include="Volo.Abp.IdentityServer.EntityFrameworkCore" />--> |
||||
|
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="Volo.Abp.OpenIddict.EntityFrameworkCore" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="LINGYUN.Abp.AuditLogging.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.AuditLogging" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Authentication.QQ" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Authentication.WeChat" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Authorization.OrganizationUnits" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Aliyun.SettingManagement" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Aliyun" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Tencent.QQ" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Tencent.SettingManagement" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Tencent" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.AspNetCore.HttpOverrides" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Data.DbMigrator" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.ExceptionHandling.Emailing" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.ExceptionHandling" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation.Redis.Client" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation.Redis" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Features.LimitValidation" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Http.Client.Wrapper" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdGenerator" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.RealTime" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Wrapper" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Dynamic.Queryable.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Linq.Dynamic.Queryable" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Exporter.MiniExcel" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.FeatureManagement.Client" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Localization" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Localization.CultureMap" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Localization.Persistence" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Logging.Serilog.Elasticsearch" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Logging" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Serilog.Enrichers.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Serilog.Enrichers.UniqueId" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Sms.Aliyun" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.AspNetCore.Mvc.Wrapper" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.UI.Navigation" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenApi.Authorization" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MultiTenancy.Editions" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.WeChat" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.MiniProgram" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Official.Handlers" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Official" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Official.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Official.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.SettingManagement" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Work.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Work.Handlers" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Work.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat.Work" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WeChat" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="LINGYUN.Abp.Account.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Account.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Account.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Account.Templates" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Auditing.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Auditing.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Auditing.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.CachingManagement.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.CachingManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.CachingManagement.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.CachingManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.CachingManagement.StackExchangeRedis" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.DataProtectionManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.BlobStoring" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Emailing" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.IM" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Notifications" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Sms" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities.Webhooks" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Activities" /> |
||||
|
<!-- <PackageReference Include="LINGYUN.Abp.Elsa.EntityFrameworkCore.PostgreSql" />--> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa.Server" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Elsa" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.FeatureManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.FeatureManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.Session" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.AspNetCore.Session" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.Notifications" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.OrganizaztionUnits" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.LinkUser" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.Portal" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.SmsValidator" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IdentityServer.WeChat.Work" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Identity.Session.AspNetCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.LocalizationManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.AspNetCore.Session" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.AspNetCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IM.SignalR" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.IM" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MessageService.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MessageService.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MessageService.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MessageService.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MessageService.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.MessageService.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.ExceptionHandling.Notifications" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Common" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Core" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Emailing" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.SignalR" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.WeChat.MiniProgram" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Notifications.WeChat.Work" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.LinkUser" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.Sms" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.Portal" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.WeChat" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OpenIddict.WeChat.Work" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.FileSystem" /> |
||||
|
<!-- <PackageReference Include="LINGYUN.Abp.OssManagement.Imaging" />--> |
||||
|
<!-- <PackageReference Include="LINGYUN.Abp.OssManagement.Minio" />--> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.OssManagement.SettingManagement" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.PermissionManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.PermissionManagement.Domain.OrganizationUnits" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.PermissionManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.UI.Navigation.VueVbenAdmin" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Settings.VueVbenAdmin" /> |
||||
|
<PackageReference Include="LINGYUN.Platform.Theme.VueVbenAdmin" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Saas.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Saas.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Saas.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Saas.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Saas.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Saas.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.SettingManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.SettingManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Abstractions" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Activities" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.DistributedLocking" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.EventBus" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.ExceptionHandling" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Jobs" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Notifications" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks.Quartz" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.BackgroundTasks" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TaskManagement.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TaskManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TaskManagement.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TaskManagement.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TaskManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TaskManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TextTemplating.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TextTemplating.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TextTemplating.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TextTemplating.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TextTemplating.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.TextTemplating.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Webhooks.Core" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Webhooks.EventBus" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Webhooks.Identity" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Webhooks.Saas" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Application.Contracts" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Application" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Domain.Shared" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.Domain" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.WebhooksManagement.HttpApi" /> |
||||
|
<PackageReference Include="LINGYUN.Abp.Webhooks" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<!-- <ItemGroup>--> |
||||
|
<!-- <ProjectReference Include="..\..\modules\demo\LINGYUN.Abp.Demo.Application\LINGYUN.Abp.Demo.Application.csproj" />--> |
||||
|
<!-- <ProjectReference Include="..\..\modules\demo\LINGYUN.Abp.Demo.EntityFrameworkCore\LINGYUN.Abp.Demo.EntityFrameworkCore.csproj" />--> |
||||
|
<!-- <ProjectReference Include="..\..\modules\demo\LINGYUN.Abp.Demo.HttpApi\LINGYUN.Abp.Demo.HttpApi.csproj" />--> |
||||
|
<!-- <ProjectReference Include="..\..\modules\oss-management\LINGYUN.Abp.OssManagement.Imaging\LINGYUN.Abp.OssManagement.Imaging.csproj" />--> |
||||
|
<!-- </ItemGroup>--> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,935 @@ |
|||||
|
using Elsa; |
||||
|
using Elsa.Options; |
||||
|
using LINGYUN.Abp.Aliyun.Localization; |
||||
|
using LINGYUN.Abp.BackgroundTasks; |
||||
|
using LINGYUN.Abp.DataProtectionManagement; |
||||
|
using LINGYUN.Abp.ExceptionHandling; |
||||
|
using LINGYUN.Abp.ExceptionHandling.Emailing; |
||||
|
using LINGYUN.Abp.Exporter.MiniExcel; |
||||
|
using LINGYUN.Abp.Idempotent; |
||||
|
using LINGYUN.Abp.Identity.Session; |
||||
|
using LINGYUN.Abp.IdentityServer.IdentityResources; |
||||
|
using LINGYUN.Abp.Localization.CultureMap; |
||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using LINGYUN.Abp.OpenIddict.AspNetCore.Session; |
||||
|
using LINGYUN.Abp.OpenIddict.LinkUser; |
||||
|
using LINGYUN.Abp.OpenIddict.Permissions; |
||||
|
using LINGYUN.Abp.OpenIddict.Portal; |
||||
|
using LINGYUN.Abp.OpenIddict.Sms; |
||||
|
using LINGYUN.Abp.OpenIddict.WeChat; |
||||
|
using LINGYUN.Abp.Saas; |
||||
|
using LINGYUN.Abp.Serilog.Enrichers.Application; |
||||
|
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; |
||||
|
using LINGYUN.Abp.Tencent.Localization; |
||||
|
using LINGYUN.Abp.TextTemplating; |
||||
|
using LINGYUN.Abp.WebhooksManagement; |
||||
|
using LINGYUN.Abp.WeChat.Common.Messages.Handlers; |
||||
|
using LINGYUN.Abp.WeChat.Localization; |
||||
|
using LINGYUN.Abp.WeChat.Work; |
||||
|
using LINGYUN.Abp.Wrapper; |
||||
|
using LINGYUN.Platform.Localization; |
||||
|
using LY.AIO.Applications.Single.Authentication; |
||||
|
using LY.AIO.Applications.Single.IdentityResources; |
||||
|
using LY.AIO.Applications.Single.Microsoft.Extensions.DependencyInjection; |
||||
|
using LY.AIO.Applications.Single.WeChat.Official.Messages; |
||||
|
using Medallion.Threading; |
||||
|
using Medallion.Threading.Redis; |
||||
|
using Microsoft.AspNetCore.Authentication.Cookies; |
||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer; |
||||
|
using Microsoft.AspNetCore.Cors; |
||||
|
using Microsoft.AspNetCore.DataProtection; |
||||
|
using Microsoft.AspNetCore.Identity; |
||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core; |
||||
|
using Microsoft.Extensions.Caching.StackExchangeRedis; |
||||
|
using Microsoft.IdentityModel.Logging; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
using MiniExcelLibs.Attributes; |
||||
|
using OpenIddict.Server; |
||||
|
using OpenIddict.Server.AspNetCore; |
||||
|
using Quartz; |
||||
|
using StackExchange.Redis; |
||||
|
using System.Security.Cryptography; |
||||
|
using System.Security.Cryptography.X509Certificates; |
||||
|
using System.Text.Encodings.Web; |
||||
|
using System.Text.Unicode; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
using Volo.Abp.AspNetCore.Mvc.AntiForgery; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
using Volo.Abp.Auditing; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.BlobStoring; |
||||
|
using Volo.Abp.BlobStoring.FileSystem; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
using Volo.Abp.FeatureManagement; |
||||
|
using Volo.Abp.Features; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Identity.Localization; |
||||
|
using Volo.Abp.IdentityServer; |
||||
|
using Volo.Abp.IdentityServer.Localization; |
||||
|
using Volo.Abp.Json; |
||||
|
using Volo.Abp.Json.SystemTextJson; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.OpenIddict; |
||||
|
using Volo.Abp.OpenIddict.Localization; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.Quartz; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
using Volo.Abp.SettingManagement; |
||||
|
using Volo.Abp.SettingManagement.Localization; |
||||
|
using Volo.Abp.Threading; |
||||
|
using Volo.Abp.UI.Navigation.Urls; |
||||
|
using Volo.Abp.VirtualFileSystem; |
||||
|
using VoloAbpExceptionHandlingOptions = Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingOptions; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single; |
||||
|
|
||||
|
public partial class MicroServiceApplicationsSingleModule |
||||
|
{ |
||||
|
protected const string DefaultCorsPolicyName = "Default"; |
||||
|
public static string ApplicationName { get; set; } = "MicroService-Applications-Single"; |
||||
|
private readonly static OneTimeRunner OneTimeRunner = new(); |
||||
|
|
||||
|
private void PreConfigureFeature() |
||||
|
{ |
||||
|
OneTimeRunner.Run(() => |
||||
|
{ |
||||
|
GlobalFeatureManager.Instance.Modules.Editions().EnableAll(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureApp(IConfiguration configuration) |
||||
|
{ |
||||
|
AbpSerilogEnrichersConsts.ApplicationName = ApplicationName; |
||||
|
|
||||
|
PreConfigure<AbpSerilogEnrichersUniqueIdOptions>(options => |
||||
|
{ |
||||
|
// 以开放端口区别,应在0-31之间
|
||||
|
options.SnowflakeIdOptions.WorkerId = 1; |
||||
|
options.SnowflakeIdOptions.WorkerIdBits = 5; |
||||
|
options.SnowflakeIdOptions.DatacenterId = 1; |
||||
|
}); |
||||
|
|
||||
|
if (configuration.GetValue<bool>("App:ShowPii")) |
||||
|
{ |
||||
|
IdentityModelEventSource.ShowPII = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureAuthServer(IConfiguration configuration) |
||||
|
{ |
||||
|
PreConfigure<OpenIddictBuilder>(builder => |
||||
|
{ |
||||
|
builder.AddValidation(options => |
||||
|
{ |
||||
|
//options.AddAudiences("lingyun-abp-application");
|
||||
|
|
||||
|
options.UseLocalServer(); |
||||
|
|
||||
|
options.UseAspNetCore(); |
||||
|
|
||||
|
options.UseDataProtection(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureIdentity() |
||||
|
{ |
||||
|
PreConfigure<IdentityBuilder>(builder => |
||||
|
{ |
||||
|
builder.AddDefaultTokenProviders(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureCertificate(IConfiguration configuration, IWebHostEnvironment environment) |
||||
|
{ |
||||
|
var cerConfig = configuration.GetSection("Certificates"); |
||||
|
if (environment.IsProduction() && cerConfig.Exists()) |
||||
|
{ |
||||
|
// 开发环境下存在证书配置
|
||||
|
// 且证书文件存在则使用自定义的证书文件来启动Ids服务器
|
||||
|
var cerPath = Path.Combine(environment.ContentRootPath, cerConfig["CerPath"]); |
||||
|
if (File.Exists(cerPath)) |
||||
|
{ |
||||
|
var certificate = new X509Certificate2(cerPath, cerConfig["Password"]); |
||||
|
|
||||
|
if (configuration.GetValue<bool>("AuthServer:UseOpenIddict")) |
||||
|
{ |
||||
|
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options => |
||||
|
{ |
||||
|
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
|
||||
|
options.AddDevelopmentEncryptionAndSigningCertificate = false; |
||||
|
}); |
||||
|
|
||||
|
PreConfigure<OpenIddictServerBuilder>(builder => |
||||
|
{ |
||||
|
builder.AddSigningCertificate(certificate); |
||||
|
builder.AddEncryptionCertificate(certificate); |
||||
|
|
||||
|
builder.UseDataProtection(); |
||||
|
|
||||
|
// 禁用https
|
||||
|
builder.UseAspNetCore() |
||||
|
.DisableTransportSecurityRequirement(); |
||||
|
}); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
PreConfigure<AbpIdentityServerBuilderOptions>(options => |
||||
|
{ |
||||
|
options.AddDeveloperSigningCredential = false; |
||||
|
}); |
||||
|
|
||||
|
PreConfigure<IIdentityServerBuilder>(builder => |
||||
|
{ |
||||
|
builder.AddSigningCredential(certificate); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("AuthServer:UseOpenIddict")) |
||||
|
{ |
||||
|
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options => |
||||
|
{ |
||||
|
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
|
||||
|
options.AddDevelopmentEncryptionAndSigningCertificate = false; |
||||
|
}); |
||||
|
|
||||
|
PreConfigure<OpenIddictServerBuilder>(builder => |
||||
|
{ |
||||
|
//https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
|
||||
|
using (var algorithm = RSA.Create(keySizeInBits: 2048)) |
||||
|
{ |
||||
|
var subject = new X500DistinguishedName("CN=Fabrikam Encryption Certificate"); |
||||
|
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); |
||||
|
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, critical: true)); |
||||
|
var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); |
||||
|
builder.AddSigningCertificate(certificate); |
||||
|
} |
||||
|
|
||||
|
using (var algorithm = RSA.Create(keySizeInBits: 2048)) |
||||
|
{ |
||||
|
var subject = new X500DistinguishedName("CN=Fabrikam Signing Certificate"); |
||||
|
var request = new CertificateRequest(subject, algorithm, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); |
||||
|
request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, critical: true)); |
||||
|
var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(2)); |
||||
|
builder.AddEncryptionCertificate(certificate); |
||||
|
} |
||||
|
|
||||
|
builder.UseDataProtection(); |
||||
|
|
||||
|
// 禁用https
|
||||
|
builder.UseAspNetCore() |
||||
|
.DisableTransportSecurityRequirement(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureQuartz(IConfiguration configuration) |
||||
|
{ |
||||
|
PreConfigure<AbpQuartzOptions>(options => |
||||
|
{ |
||||
|
// 如果使用持久化存储, 则配置quartz持久层
|
||||
|
if (configuration.GetSection("Quartz:UsePersistentStore").Get<bool>()) |
||||
|
{ |
||||
|
var settings = configuration.GetSection("Quartz:Properties").Get<Dictionary<string, string>>(); |
||||
|
if (settings != null) |
||||
|
{ |
||||
|
foreach (var setting in settings) |
||||
|
{ |
||||
|
options.Properties[setting.Key] = setting.Value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
options.Configurator += (config) => |
||||
|
{ |
||||
|
config.UsePersistentStore(store => |
||||
|
{ |
||||
|
store.UseProperties = false; |
||||
|
store.UseNewtonsoftJsonSerializer(); |
||||
|
}); |
||||
|
}; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureElsa(IServiceCollection services, IConfiguration configuration) |
||||
|
{ |
||||
|
var elsaSection = configuration.GetSection("Elsa"); |
||||
|
var startups = new[] |
||||
|
{ |
||||
|
typeof(Elsa.Activities.Console.Startup), |
||||
|
typeof(Elsa.Activities.Http.Startup), |
||||
|
typeof(Elsa.Activities.UserTask.Startup), |
||||
|
typeof(Elsa.Activities.Temporal.Quartz.Startup), |
||||
|
typeof(Elsa.Activities.Email.Startup), |
||||
|
typeof(Elsa.Scripting.JavaScript.Startup), |
||||
|
typeof(Elsa.Activities.Webhooks.Startup), |
||||
|
}; |
||||
|
|
||||
|
PreConfigure<ElsaOptionsBuilder>(elsa => |
||||
|
{ |
||||
|
elsa |
||||
|
.AddActivitiesFrom<MicroServiceApplicationsSingleModule>() |
||||
|
.AddWorkflowsFrom<MicroServiceApplicationsSingleModule>() |
||||
|
.AddFeatures(startups, configuration) |
||||
|
.ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)); |
||||
|
|
||||
|
elsa.DistributedLockingOptionsBuilder |
||||
|
.UseProviderFactory(sp => name => |
||||
|
{ |
||||
|
var provider = sp.GetRequiredService<IDistributedLockProvider>(); |
||||
|
|
||||
|
return provider.CreateLock(name); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
services.AddNotificationHandlersFrom<MicroServiceApplicationsSingleModule>(); |
||||
|
|
||||
|
PreConfigure<IMvcBuilder>(mvcBuilder => |
||||
|
{ |
||||
|
mvcBuilder.AddApplicationPartIfNotExists(typeof(Elsa.Webhooks.Api.Endpoints.List).Assembly); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureAuthServer(IConfiguration configuration) |
||||
|
{ |
||||
|
Configure<OpenIddictServerAspNetCoreBuilder>(builder => |
||||
|
{ |
||||
|
builder.DisableTransportSecurityRequirement(); |
||||
|
}); |
||||
|
|
||||
|
Configure<OpenIddictServerAspNetCoreOptions>(options => |
||||
|
{ |
||||
|
options.DisableTransportSecurityRequirement = true; |
||||
|
}); |
||||
|
|
||||
|
Configure<OpenIddictServerOptions>(options => |
||||
|
{ |
||||
|
var lifetime = configuration.GetSection("OpenIddict:Lifetime"); |
||||
|
options.AuthorizationCodeLifetime = lifetime.GetValue("AuthorizationCode", options.AuthorizationCodeLifetime); |
||||
|
options.AccessTokenLifetime = lifetime.GetValue("AccessToken", options.AccessTokenLifetime); |
||||
|
options.DeviceCodeLifetime = lifetime.GetValue("DeviceCode", options.DeviceCodeLifetime); |
||||
|
options.IdentityTokenLifetime = lifetime.GetValue("IdentityToken", options.IdentityTokenLifetime); |
||||
|
options.RefreshTokenLifetime = lifetime.GetValue("RefreshToken", options.RefreshTokenLifetime); |
||||
|
options.RefreshTokenReuseLeeway = lifetime.GetValue("RefreshTokenReuseLeeway", options.RefreshTokenReuseLeeway); |
||||
|
options.UserCodeLifetime = lifetime.GetValue("UserCode", options.UserCodeLifetime); |
||||
|
}); |
||||
|
Configure<AbpOpenIddictAspNetCoreSessionOptions>(options => |
||||
|
{ |
||||
|
options.PersistentSessionGrantTypes.Add(SmsTokenExtensionGrantConsts.GrantType); |
||||
|
options.PersistentSessionGrantTypes.Add(PortalTokenExtensionGrantConsts.GrantType); |
||||
|
options.PersistentSessionGrantTypes.Add(LinkUserTokenExtensionGrantConsts.GrantType); |
||||
|
options.PersistentSessionGrantTypes.Add(WeChatTokenExtensionGrantConsts.OfficialGrantType); |
||||
|
options.PersistentSessionGrantTypes.Add(WeChatTokenExtensionGrantConsts.MiniProgramGrantType); |
||||
|
options.PersistentSessionGrantTypes.Add(AbpWeChatWorkGlobalConsts.GrantType); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureEndpoints(IServiceCollection services) |
||||
|
{ |
||||
|
// 不需要
|
||||
|
//Configure<AbpEndpointRouterOptions>(options =>
|
||||
|
//{
|
||||
|
// options.EndpointConfigureActions.Add(
|
||||
|
// (context) =>
|
||||
|
// {
|
||||
|
// context.Endpoints.MapFallbackToPage("/_Host");
|
||||
|
// });
|
||||
|
//});
|
||||
|
var preActions = services.GetPreConfigureActions<AbpAspNetCoreMvcOptions>(); |
||||
|
|
||||
|
services.AddAbpApiVersioning(options => |
||||
|
{ |
||||
|
options.ReportApiVersions = true; |
||||
|
options.AssumeDefaultVersionWhenUnspecified = true; |
||||
|
|
||||
|
//options.ApiVersionReader = new HeaderApiVersionReader("api-version"); //Supports header too
|
||||
|
//options.ApiVersionReader = new MediaTypeApiVersionReader(); //Supports accept header too
|
||||
|
}, mvcOptions => |
||||
|
{ |
||||
|
mvcOptions.ConfigureAbp(preActions.Configure()); |
||||
|
}); |
||||
|
|
||||
|
//services.AddApiVersioning(config =>
|
||||
|
//{
|
||||
|
// // Specify the default API Version as 1.0
|
||||
|
// config.DefaultApiVersion = new ApiVersion(1, 0);
|
||||
|
// // Advertise the API versions supported for the particular endpoint (through 'api-supported-versions' response header which lists all available API versions for that endpoint)
|
||||
|
// config.ReportApiVersions = true;
|
||||
|
//});
|
||||
|
|
||||
|
//services.AddVersionedApiExplorer(options =>
|
||||
|
//{
|
||||
|
// // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
|
||||
|
// // note: the specified format code will format the version as "'v'major[.minor][-status]"
|
||||
|
// options.GroupNameFormat = "'v'VVV";
|
||||
|
|
||||
|
// // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
|
||||
|
// // can also be used to control the format of the API version in route templates
|
||||
|
// options.SubstituteApiVersionInUrl = true;
|
||||
|
//});
|
||||
|
} |
||||
|
|
||||
|
private void ConfigureKestrelServer() |
||||
|
{ |
||||
|
Configure<KestrelServerOptions>(options => |
||||
|
{ |
||||
|
options.Limits.MaxRequestBodySize = null; |
||||
|
options.Limits.MaxRequestBufferSize = null; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureBlobStoring(IConfiguration configuration) |
||||
|
{ |
||||
|
Configure<AbpBlobStoringOptions>(options => |
||||
|
{ |
||||
|
options.Containers.ConfigureAll((containerName, containerConfiguration) => |
||||
|
{ |
||||
|
containerConfiguration.UseFileSystem(fileSystem => |
||||
|
{ |
||||
|
fileSystem.BasePath = Path.Combine(Directory.GetCurrentDirectory(), "blobs"); |
||||
|
}); |
||||
|
|
||||
|
//containerConfiguration.UseMinio(minio =>
|
||||
|
//{
|
||||
|
// configuration.GetSection("Minio").Bind(minio);
|
||||
|
//});
|
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureBackgroundTasks() |
||||
|
{ |
||||
|
Configure<AbpBackgroundTasksOptions>(options => |
||||
|
{ |
||||
|
options.NodeName = ApplicationName; |
||||
|
options.JobCleanEnabled = true; |
||||
|
options.JobFetchEnabled = true; |
||||
|
options.JobCheckEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureTextTemplating(IConfiguration configuration) |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("TextTemplating:IsDynamicStoreEnabled")) |
||||
|
{ |
||||
|
Configure<AbpTextTemplatingCachingOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicTemplateDefinitionStoreEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureFeatureManagement(IConfiguration configuration) |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("FeatureManagement:IsDynamicStoreEnabled")) |
||||
|
{ |
||||
|
Configure<FeatureManagementOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicFeatureStoreEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
Configure<FeatureManagementOptions>(options => |
||||
|
{ |
||||
|
options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = AbpSaasPermissions.Editions.ManageFeatures; |
||||
|
options.ProviderPolicies[TenantFeatureValueProvider.ProviderName] = AbpSaasPermissions.Tenants.ManageFeatures; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureSettingManagement(IConfiguration configuration) |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("SettingManagement:IsDynamicStoreEnabled")) |
||||
|
{ |
||||
|
Configure<SettingManagementOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicSettingStoreEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureWebhooksManagement(IConfiguration configuration) |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("WebhooksManagement:IsDynamicStoreEnabled")) |
||||
|
{ |
||||
|
Configure<WebhooksManagementOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicWebhookStoreEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 配置数据导出
|
||||
|
/// </summary>
|
||||
|
private void ConfigureExporter() |
||||
|
{ |
||||
|
Configure<AbpExporterMiniExcelOptions>(options => |
||||
|
{ |
||||
|
// options.MapExportSetting(typeof(BookDto), config =>
|
||||
|
// {
|
||||
|
// config.DynamicColumns = new[]
|
||||
|
// {
|
||||
|
// // 忽略某些字段
|
||||
|
// new DynamicExcelColumn(nameof(BookDto.AuthorId)){ Ignore = true },
|
||||
|
// new DynamicExcelColumn(nameof(BookDto.LastModificationTime)){ Ignore = true },
|
||||
|
// new DynamicExcelColumn(nameof(BookDto.LastModifierId)){ Ignore = true },
|
||||
|
// new DynamicExcelColumn(nameof(BookDto.CreationTime)){ Ignore = true },
|
||||
|
// new DynamicExcelColumn(nameof(BookDto.CreatorId)){ Ignore = true },
|
||||
|
// new DynamicExcelColumn(nameof(BookDto.Id)){ Ignore = true },
|
||||
|
// };
|
||||
|
// });
|
||||
|
}); |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 配置数据权限
|
||||
|
/// </summary>
|
||||
|
private void ConfigureEntityDataProtected() |
||||
|
{ |
||||
|
// Configure<DataProtectionManagementOptions>(options =>
|
||||
|
// {
|
||||
|
// options.AddEntities(typeof(DemoResource),
|
||||
|
// new[]
|
||||
|
// {
|
||||
|
// typeof(Book),
|
||||
|
// });
|
||||
|
// });
|
||||
|
} |
||||
|
|
||||
|
private void ConfigurePermissionManagement(IConfiguration configuration) |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("PermissionManagement:IsDynamicStoreEnabled")) |
||||
|
{ |
||||
|
Configure<PermissionManagementOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicPermissionStoreEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
Configure<PermissionManagementOptions>(options => |
||||
|
{ |
||||
|
// Rename IdentityServer.Client.ManagePermissions
|
||||
|
// See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs
|
||||
|
options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpOpenIddictPermissions.Applications.ManagePermissions; |
||||
|
|
||||
|
//if (configuration.GetValue<bool>("AuthServer:UseOpenIddict"))
|
||||
|
//{
|
||||
|
// options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpOpenIddictPermissions.Applications.ManagePermissions;
|
||||
|
//}
|
||||
|
//else
|
||||
|
//{
|
||||
|
// options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpIdentityServerPermissions.Clients.ManagePermissions;
|
||||
|
//}
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureNotificationManagement(IConfiguration configuration) |
||||
|
{ |
||||
|
if (configuration.GetValue<bool>("NotificationsManagement:IsDynamicStoreEnabled")) |
||||
|
{ |
||||
|
Configure<AbpNotificationsManagementOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicNotificationsStoreEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration) |
||||
|
{ |
||||
|
var distributedLockEnabled = configuration["DistributedLock:IsEnabled"]; |
||||
|
if (distributedLockEnabled.IsNullOrEmpty() || bool.Parse(distributedLockEnabled)) |
||||
|
{ |
||||
|
var redis = ConnectionMultiplexer.Connect(configuration["DistributedLock:Redis:Configuration"]); |
||||
|
services.AddSingleton<IDistributedLockProvider>(_ => new RedisDistributedSynchronizationProvider(redis.GetDatabase())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureVirtualFileSystem() |
||||
|
{ |
||||
|
Configure<AbpVirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.AddEmbedded<MicroServiceApplicationsSingleModule>("LY.MicroService.Applications.Single"); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureIdempotent() |
||||
|
{ |
||||
|
Configure<AbpIdempotentOptions>(options => |
||||
|
{ |
||||
|
options.IsEnabled = true; |
||||
|
options.DefaultTimeout = 0; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureDbContext() |
||||
|
{ |
||||
|
Configure<AbpDbContextOptions>(options => |
||||
|
{ |
||||
|
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);//解决PostgreSql设置为utc时间后无法写入local时区的问题
|
||||
|
options.UseNpgsql(); |
||||
|
|
||||
|
// options.UseMySQL();
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureDataSeeder() |
||||
|
{ |
||||
|
Configure<CustomIdentityResourceDataSeederOptions>(options => |
||||
|
{ |
||||
|
options.Resources.Add(new CustomIdentityResources.AvatarUrl()); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureExceptionHandling() |
||||
|
{ |
||||
|
// 自定义需要处理的异常
|
||||
|
Configure<AbpExceptionHandlingOptions>(options => |
||||
|
{ |
||||
|
// 加入需要处理的异常类型
|
||||
|
options.Handlers.Add<Volo.Abp.Data.AbpDbConcurrencyException>(); |
||||
|
options.Handlers.Add<AbpInitializationException>(); |
||||
|
options.Handlers.Add<OutOfMemoryException>(); |
||||
|
options.Handlers.Add<System.Data.Common.DbException>(); |
||||
|
options.Handlers.Add<global::Microsoft.EntityFrameworkCore.DbUpdateException>(); |
||||
|
options.Handlers.Add<System.Data.DBConcurrencyException>(); |
||||
|
}); |
||||
|
// 自定义需要发送邮件通知的异常类型
|
||||
|
Configure<AbpEmailExceptionHandlingOptions>(options => |
||||
|
{ |
||||
|
// 是否发送堆栈信息
|
||||
|
options.SendStackTrace = true; |
||||
|
// 未指定异常接收者的默认接收邮件
|
||||
|
// 指定自己的邮件地址
|
||||
|
}); |
||||
|
|
||||
|
Configure<VoloAbpExceptionHandlingOptions>(options => |
||||
|
{ |
||||
|
options.SendStackTraceToClients = false; |
||||
|
options.SendExceptionsDetailsToClients = false; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureJsonSerializer(IConfiguration configuration) |
||||
|
{ |
||||
|
// 统一时间日期格式
|
||||
|
Configure<AbpJsonOptions>(options => |
||||
|
{ |
||||
|
var jsonConfiguration = configuration.GetSection("Json"); |
||||
|
if (jsonConfiguration.Exists()) |
||||
|
{ |
||||
|
jsonConfiguration.Bind(options); |
||||
|
} |
||||
|
}); |
||||
|
// 中文序列化的编码问题
|
||||
|
Configure<AbpSystemTextJsonSerializerOptions>(options => |
||||
|
{ |
||||
|
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureCaching(IConfiguration configuration) |
||||
|
{ |
||||
|
Configure<AbpDistributedCacheOptions>(options => |
||||
|
{ |
||||
|
configuration.GetSection("DistributedCache").Bind(options); |
||||
|
}); |
||||
|
|
||||
|
Configure<RedisCacheOptions>(options => |
||||
|
{ |
||||
|
var redisConfig = ConfigurationOptions.Parse(options.Configuration); |
||||
|
options.ConfigurationOptions = redisConfig; |
||||
|
options.InstanceName = configuration["Redis:InstanceName"]; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureMultiTenancy(IConfiguration configuration) |
||||
|
{ |
||||
|
// 多租户
|
||||
|
Configure<AbpMultiTenancyOptions>(options => |
||||
|
{ |
||||
|
options.IsEnabled = true; |
||||
|
}); |
||||
|
|
||||
|
var tenantResolveCfg = configuration.GetSection("App:Domains"); |
||||
|
if (tenantResolveCfg.Exists()) |
||||
|
{ |
||||
|
Configure<AbpTenantResolveOptions>(options => |
||||
|
{ |
||||
|
var domains = tenantResolveCfg.Get<string[]>(); |
||||
|
foreach (var domain in domains) |
||||
|
{ |
||||
|
options.AddDomainTenantResolver(domain); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureAuditing(IConfiguration configuration) |
||||
|
{ |
||||
|
Configure<AbpAuditingOptions>(options => |
||||
|
{ |
||||
|
options.ApplicationName = ApplicationName; |
||||
|
// 是否启用实体变更记录
|
||||
|
var allEntitiesSelectorIsEnabled = configuration["Auditing:AllEntitiesSelector"]; |
||||
|
if (allEntitiesSelectorIsEnabled.IsNullOrWhiteSpace() || |
||||
|
(bool.TryParse(allEntitiesSelectorIsEnabled, out var enabled) && enabled)) |
||||
|
{ |
||||
|
options.EntityHistorySelectors.AddAllEntities(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureSwagger(IServiceCollection services) |
||||
|
{ |
||||
|
// Swagger
|
||||
|
services.AddSwaggerGen( |
||||
|
options => |
||||
|
{ |
||||
|
options.SwaggerDoc("v1", new OpenApiInfo { Title = "App API", Version = "v1" }); |
||||
|
options.DocInclusionPredicate((docName, description) => true); |
||||
|
options.CustomSchemaIds(type => type.FullName); |
||||
|
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", |
||||
|
Name = "Authorization", |
||||
|
In = ParameterLocation.Header, |
||||
|
Scheme = "bearer", |
||||
|
Type = SecuritySchemeType.Http, |
||||
|
BearerFormat = "JWT" |
||||
|
}); |
||||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
||||
|
{ |
||||
|
{ |
||||
|
new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } |
||||
|
}, |
||||
|
new string[] { } |
||||
|
} |
||||
|
}); |
||||
|
options.OperationFilter<TenantHeaderParamter>(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureIdentity(IConfiguration configuration) |
||||
|
{ |
||||
|
// 增加配置文件定义,在新建租户时需要
|
||||
|
Configure<IdentityOptions>(options => |
||||
|
{ |
||||
|
var identityConfiguration = configuration.GetSection("Identity"); |
||||
|
if (identityConfiguration.Exists()) |
||||
|
{ |
||||
|
identityConfiguration.Bind(options); |
||||
|
} |
||||
|
}); |
||||
|
Configure<AbpClaimsPrincipalFactoryOptions>(options => |
||||
|
{ |
||||
|
options.IsDynamicClaimsEnabled = true; |
||||
|
}); |
||||
|
Configure<IdentitySessionCleanupOptions>(options => |
||||
|
{ |
||||
|
options.IsCleanupEnabled = true; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureMvcUiTheme() |
||||
|
{ |
||||
|
Configure<AbpBundlingOptions>(options => |
||||
|
{ |
||||
|
//options.StyleBundles.Configure(
|
||||
|
// LeptonXLiteThemeBundles.Styles.Global,
|
||||
|
// bundle =>
|
||||
|
// {
|
||||
|
// bundle.AddFiles("/global-styles.css");
|
||||
|
// }
|
||||
|
//);
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureLocalization() |
||||
|
{ |
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
||||
|
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
||||
|
|
||||
|
options |
||||
|
.AddLanguagesMapOrUpdate( |
||||
|
"vue-admin-element-ui", |
||||
|
new NameValue("zh-Hans", "zh"), |
||||
|
new NameValue("en", "en")); |
||||
|
|
||||
|
// vben admin 语言映射
|
||||
|
options |
||||
|
.AddLanguagesMapOrUpdate( |
||||
|
"vben-admin-ui", |
||||
|
new NameValue("zh_CN", "zh-Hans")); |
||||
|
|
||||
|
options.Resources.Get<AbpSettingManagementResource>() |
||||
|
.AddBaseTypes( |
||||
|
typeof(IdentityResource), |
||||
|
typeof(AliyunResource), |
||||
|
typeof(TencentCloudResource), |
||||
|
typeof(WeChatResource), |
||||
|
typeof(PlatformResource), |
||||
|
typeof(AbpOpenIddictResource), |
||||
|
typeof(AbpIdentityServerResource)); |
||||
|
|
||||
|
options.UseAllPersistence(); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpLocalizationCultureMapOptions>(options => |
||||
|
{ |
||||
|
var zhHansCultureMapInfo = new CultureMapInfo |
||||
|
{ |
||||
|
TargetCulture = "zh-Hans", |
||||
|
SourceCultures = new string[] { "zh", "zh_CN", "zh-CN" } |
||||
|
}; |
||||
|
|
||||
|
options.CulturesMaps.Add(zhHansCultureMapInfo); |
||||
|
options.UiCulturesMaps.Add(zhHansCultureMapInfo); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureWrapper() |
||||
|
{ |
||||
|
Configure<AbpWrapperOptions>(options => |
||||
|
{ |
||||
|
options.IsEnabled = true; |
||||
|
// options.IsWrapUnauthorizedEnabled = true;
|
||||
|
options.IgnoreNamespaces.Add("Elsa"); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void PreConfigureWrapper() |
||||
|
{ |
||||
|
//PreConfigure<AbpDaprClientProxyOptions>(options =>
|
||||
|
//{
|
||||
|
// options.ProxyRequestActions.Add(
|
||||
|
// (appid, httprequestmessage) =>
|
||||
|
// {
|
||||
|
// httprequestmessage.Headers.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true");
|
||||
|
// });
|
||||
|
//});
|
||||
|
|
||||
|
PreConfigure<AbpHttpClientBuilderOptions>(options => |
||||
|
{ |
||||
|
options.ProxyClientActions.Add( |
||||
|
(_, _, client) => |
||||
|
{ |
||||
|
client.DefaultRequestHeaders.TryAddWithoutValidation(AbpHttpWrapConsts.AbpDontWrapResult, "true"); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureAuditing() |
||||
|
{ |
||||
|
Configure<AbpAuditingOptions>(options => |
||||
|
{ |
||||
|
// options.IsEnabledForGetRequests = true;
|
||||
|
options.ApplicationName = ApplicationName; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureUrls(IConfiguration configuration) |
||||
|
{ |
||||
|
Configure<AppUrlOptions>(options => |
||||
|
{ |
||||
|
var applicationConfiguration = configuration.GetSection("App:Urls:Applications"); |
||||
|
foreach (var appConfig in applicationConfiguration.GetChildren()) |
||||
|
{ |
||||
|
options.Applications[appConfig.Key].RootUrl = appConfig["RootUrl"]; |
||||
|
foreach (var urlsConfig in appConfig.GetSection("Urls").GetChildren()) |
||||
|
{ |
||||
|
options.Applications[appConfig.Key].Urls[urlsConfig.Key] = urlsConfig.Value; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureSecurity(IServiceCollection services, IConfiguration configuration, bool isDevelopment = false) |
||||
|
{ |
||||
|
Configure<AbpAntiForgeryOptions>(options => |
||||
|
{ |
||||
|
options.AutoValidate = false; |
||||
|
}); |
||||
|
|
||||
|
services.Replace<CookieAuthenticationHandler, AbpCookieAuthenticationHandler>(ServiceLifetime.Scoped); |
||||
|
|
||||
|
services.AddAuthentication() |
||||
|
.AddAbpJwtBearer(options => |
||||
|
{ |
||||
|
configuration.GetSection("AuthServer").Bind(options); |
||||
|
|
||||
|
options.Events ??= new JwtBearerEvents(); |
||||
|
options.Events.OnMessageReceived = context => |
||||
|
{ |
||||
|
var accessToken = context.Request.Query["access_token"]; |
||||
|
var path = context.HttpContext.Request.Path; |
||||
|
if (!string.IsNullOrEmpty(accessToken) && |
||||
|
(path.StartsWithSegments("/api/files"))) |
||||
|
{ |
||||
|
context.Token = accessToken; |
||||
|
} |
||||
|
return Task.CompletedTask; |
||||
|
}; |
||||
|
}); |
||||
|
|
||||
|
if (!isDevelopment) |
||||
|
{ |
||||
|
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
||||
|
services |
||||
|
.AddDataProtection() |
||||
|
.SetApplicationName("LINGYUN.Abp.Application") |
||||
|
.PersistKeysToStackExchangeRedis(redis, "LINGYUN.Abp.Application:DataProtection:Protection-Keys"); |
||||
|
} |
||||
|
|
||||
|
services.AddSameSiteCookiePolicy(); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureCors(IServiceCollection services, IConfiguration configuration) |
||||
|
{ |
||||
|
services.AddCors(options => |
||||
|
{ |
||||
|
options.AddPolicy(DefaultCorsPolicyName, builder => |
||||
|
{ |
||||
|
builder |
||||
|
.WithOrigins( |
||||
|
configuration["App:CorsOrigins"] |
||||
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
||||
|
.Select(o => o.RemovePostFix("/")) |
||||
|
.ToArray() |
||||
|
) |
||||
|
.WithAbpExposedHeaders() |
||||
|
.WithAbpWrapExposedHeaders() |
||||
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
||||
|
.AllowAnyHeader() |
||||
|
.AllowAnyMethod() |
||||
|
.AllowCredentials(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void ConfigureWeChat() |
||||
|
{ |
||||
|
Configure<AbpWeChatMessageHandleOptions>(options => |
||||
|
{ |
||||
|
// 回复文本消息
|
||||
|
options.MapMessage< |
||||
|
LINGYUN.Abp.WeChat.Official.Messages.Models.TextMessage, |
||||
|
TextMessageReplyContributor>(); |
||||
|
// 处理关注事件
|
||||
|
options.MapEvent< |
||||
|
LINGYUN.Abp.WeChat.Official.Messages.Models.UserSubscribeEvent, |
||||
|
UserSubscribeEventContributor>(); |
||||
|
|
||||
|
options.MapMessage< |
||||
|
LINGYUN.Abp.WeChat.Work.Common.Messages.Models.TextMessage, |
||||
|
WeChat.Work.Messages.TextMessageReplyContributor>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,394 @@ |
|||||
|
using LINGYUN.Abp.Account; |
||||
|
using LINGYUN.Abp.Account.Templates; |
||||
|
using LINGYUN.Abp.Aliyun.SettingManagement; |
||||
|
using LINGYUN.Abp.AspNetCore.HttpOverrides; |
||||
|
using LINGYUN.Abp.AspNetCore.Mvc.Idempotent.Wrapper; |
||||
|
using LINGYUN.Abp.AspNetCore.Mvc.Localization; |
||||
|
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; |
||||
|
using LINGYUN.Abp.Auditing; |
||||
|
using LINGYUN.Abp.AuditLogging.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.Authentication.QQ; |
||||
|
using LINGYUN.Abp.Authentication.WeChat; |
||||
|
using LINGYUN.Abp.Authorization.OrganizationUnits; |
||||
|
using LINGYUN.Abp.BackgroundTasks; |
||||
|
using LINGYUN.Abp.BackgroundTasks.Activities; |
||||
|
using LINGYUN.Abp.BackgroundTasks.DistributedLocking; |
||||
|
using LINGYUN.Abp.BackgroundTasks.EventBus; |
||||
|
using LINGYUN.Abp.BackgroundTasks.ExceptionHandling; |
||||
|
using LINGYUN.Abp.BackgroundTasks.Jobs; |
||||
|
using LINGYUN.Abp.BackgroundTasks.Notifications; |
||||
|
using LINGYUN.Abp.BackgroundTasks.Quartz; |
||||
|
using LINGYUN.Abp.CachingManagement; |
||||
|
using LINGYUN.Abp.CachingManagement.StackExchangeRedis; |
||||
|
using LINGYUN.Abp.Dapr.Client; |
||||
|
using LINGYUN.Abp.Data.DbMigrator; |
||||
|
using LINGYUN.Abp.DataProtectionManagement; |
||||
|
using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore; |
||||
|
// using LINGYUN.Abp.Demo;
|
||||
|
// using LINGYUN.Abp.Demo.EntityFrameworkCore;
|
||||
|
using LINGYUN.Abp.ExceptionHandling; |
||||
|
using LINGYUN.Abp.ExceptionHandling.Emailing; |
||||
|
using LINGYUN.Abp.Exporter.MiniExcel; |
||||
|
using LINGYUN.Abp.FeatureManagement; |
||||
|
using LINGYUN.Abp.FeatureManagement.HttpApi; |
||||
|
using LINGYUN.Abp.Features.LimitValidation; |
||||
|
using LINGYUN.Abp.Features.LimitValidation.Redis.Client; |
||||
|
using LINGYUN.Abp.Http.Client.Wrapper; |
||||
|
using LINGYUN.Abp.Identity; |
||||
|
using LINGYUN.Abp.Identity.AspNetCore.Session; |
||||
|
using LINGYUN.Abp.Identity.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.Identity.Notifications; |
||||
|
using LINGYUN.Abp.Identity.OrganizaztionUnits; |
||||
|
using LINGYUN.Abp.Identity.Session.AspNetCore; |
||||
|
using LINGYUN.Abp.Identity.WeChat; |
||||
|
using LINGYUN.Abp.IdGenerator; |
||||
|
using LINGYUN.Abp.IM.SignalR; |
||||
|
using LINGYUN.Abp.Localization.CultureMap; |
||||
|
using LINGYUN.Abp.Localization.Persistence; |
||||
|
using LINGYUN.Abp.LocalizationManagement; |
||||
|
using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.MessageService; |
||||
|
using LINGYUN.Abp.MessageService.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.MultiTenancy.Editions; |
||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using LINGYUN.Abp.Notifications.Common; |
||||
|
using LINGYUN.Abp.Notifications.Emailing; |
||||
|
using LINGYUN.Abp.Notifications.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.Notifications.SignalR; |
||||
|
using LINGYUN.Abp.Notifications.WeChat.MiniProgram; |
||||
|
using LINGYUN.Abp.OpenApi.Authorization; |
||||
|
using LINGYUN.Abp.OpenIddict; |
||||
|
using LINGYUN.Abp.OpenIddict.AspNetCore; |
||||
|
using LINGYUN.Abp.OpenIddict.AspNetCore.Session; |
||||
|
using LINGYUN.Abp.OpenIddict.Portal; |
||||
|
using LINGYUN.Abp.OpenIddict.Sms; |
||||
|
using LINGYUN.Abp.OpenIddict.WeChat; |
||||
|
using LINGYUN.Abp.OpenIddict.WeChat.Work; |
||||
|
using LINGYUN.Abp.OssManagement; |
||||
|
using LINGYUN.Abp.OssManagement.FileSystem; |
||||
|
// using LINGYUN.Abp.OssManagement.Imaging;
|
||||
|
using LINGYUN.Abp.OssManagement.SettingManagement; |
||||
|
using LINGYUN.Abp.PermissionManagement; |
||||
|
using LINGYUN.Abp.PermissionManagement.HttpApi; |
||||
|
using LINGYUN.Abp.PermissionManagement.OrganizationUnits; |
||||
|
using LINGYUN.Abp.Saas; |
||||
|
using LINGYUN.Abp.Saas.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.Serilog.Enrichers.Application; |
||||
|
using LINGYUN.Abp.Serilog.Enrichers.UniqueId; |
||||
|
using LINGYUN.Abp.SettingManagement; |
||||
|
using LINGYUN.Abp.Sms.Aliyun; |
||||
|
using LINGYUN.Abp.TaskManagement; |
||||
|
using LINGYUN.Abp.TaskManagement.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.Tencent.QQ; |
||||
|
using LINGYUN.Abp.Tencent.SettingManagement; |
||||
|
using LINGYUN.Abp.TextTemplating; |
||||
|
using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.UI.Navigation; |
||||
|
using LINGYUN.Abp.UI.Navigation.VueVbenAdmin; |
||||
|
using LINGYUN.Abp.Webhooks; |
||||
|
using LINGYUN.Abp.Webhooks.EventBus; |
||||
|
using LINGYUN.Abp.Webhooks.Identity; |
||||
|
using LINGYUN.Abp.Webhooks.Saas; |
||||
|
using LINGYUN.Abp.WebhooksManagement; |
||||
|
using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore; |
||||
|
using LINGYUN.Abp.WeChat.MiniProgram; |
||||
|
using LINGYUN.Abp.WeChat.Official; |
||||
|
using LINGYUN.Abp.WeChat.Official.Handlers; |
||||
|
using LINGYUN.Abp.WeChat.SettingManagement; |
||||
|
using LINGYUN.Abp.WeChat.Work; |
||||
|
using LINGYUN.Abp.WeChat.Work.Handlers; |
||||
|
using LINGYUN.Platform; |
||||
|
using LINGYUN.Platform.EntityFrameworkCore; |
||||
|
using LINGYUN.Platform.HttpApi; |
||||
|
using LINGYUN.Platform.Settings.VueVbenAdmin; |
||||
|
using LINGYUN.Platform.Theme.VueVbenAdmin; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Account.Web; |
||||
|
using Volo.Abp.AspNetCore.Authentication.JwtBearer; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; |
||||
|
using Volo.Abp.AspNetCore.Serilog; |
||||
|
using Volo.Abp.Autofac; |
||||
|
using Volo.Abp.Caching.StackExchangeRedis; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.EntityFrameworkCore.PostgreSql; |
||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.FeatureManagement.EntityFrameworkCore; |
||||
|
using Volo.Abp.Imaging; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.OpenIddict.EntityFrameworkCore; |
||||
|
using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
||||
|
using Volo.Abp.PermissionManagement.Identity; |
||||
|
using Volo.Abp.PermissionManagement.OpenIddict; |
||||
|
using Volo.Abp.SettingManagement; |
||||
|
using Volo.Abp.SettingManagement.EntityFrameworkCore; |
||||
|
using Volo.Abp.Threading; |
||||
|
// using LINGYUN.Abp.Elsa.EntityFrameworkCore.MySql;
|
||||
|
// using Volo.Abp.EntityFrameworkCore.MySQL;
|
||||
|
|
||||
|
namespace LY.AIO.Applications.Single; |
||||
|
|
||||
|
[DependsOn( |
||||
|
typeof(AbpAccountApplicationModule), |
||||
|
typeof(AbpAccountHttpApiModule), |
||||
|
typeof(AbpAccountWebOpenIddictModule), |
||||
|
typeof(AbpAuditingApplicationModule), |
||||
|
typeof(AbpAuditingHttpApiModule), |
||||
|
typeof(AbpAuditLoggingEntityFrameworkCoreModule), |
||||
|
typeof(AbpCachingManagementStackExchangeRedisModule), |
||||
|
typeof(AbpCachingManagementApplicationModule), |
||||
|
typeof(AbpCachingManagementHttpApiModule), |
||||
|
typeof(AbpIdentityAspNetCoreSessionModule), |
||||
|
typeof(AbpIdentitySessionAspNetCoreModule), |
||||
|
typeof(AbpIdentityNotificationsModule), |
||||
|
typeof(AbpIdentityDomainModule), |
||||
|
typeof(AbpIdentityApplicationModule), |
||||
|
typeof(AbpIdentityHttpApiModule), |
||||
|
typeof(AbpIdentityEntityFrameworkCoreModule), |
||||
|
typeof(AbpLocalizationManagementDomainModule), |
||||
|
typeof(AbpLocalizationManagementApplicationModule), |
||||
|
typeof(AbpLocalizationManagementHttpApiModule), |
||||
|
typeof(AbpLocalizationManagementEntityFrameworkCoreModule), |
||||
|
typeof(AbpSerilogEnrichersApplicationModule), |
||||
|
typeof(AbpSerilogEnrichersUniqueIdModule), |
||||
|
typeof(AbpMessageServiceDomainModule), |
||||
|
typeof(AbpMessageServiceApplicationModule), |
||||
|
typeof(AbpMessageServiceHttpApiModule), |
||||
|
typeof(AbpMessageServiceEntityFrameworkCoreModule), |
||||
|
typeof(AbpNotificationsDomainModule), |
||||
|
typeof(AbpNotificationsApplicationModule), |
||||
|
typeof(AbpNotificationsHttpApiModule), |
||||
|
typeof(AbpNotificationsEntityFrameworkCoreModule), |
||||
|
|
||||
|
//typeof(AbpIdentityServerSessionModule),
|
||||
|
//typeof(AbpIdentityServerApplicationModule),
|
||||
|
//typeof(AbpIdentityServerHttpApiModule),
|
||||
|
//typeof(AbpIdentityServerEntityFrameworkCoreModule),
|
||||
|
|
||||
|
typeof(AbpOpenIddictAspNetCoreModule), |
||||
|
typeof(AbpOpenIddictAspNetCoreSessionModule), |
||||
|
typeof(AbpOpenIddictApplicationModule), |
||||
|
typeof(AbpOpenIddictHttpApiModule), |
||||
|
typeof(AbpOpenIddictEntityFrameworkCoreModule), |
||||
|
typeof(AbpOpenIddictSmsModule), |
||||
|
typeof(AbpOpenIddictPortalModule), |
||||
|
typeof(AbpOpenIddictWeChatModule), |
||||
|
typeof(AbpOpenIddictWeChatWorkModule), |
||||
|
|
||||
|
//typeof(AbpOssManagementMinioModule), // 取消注释以使用Minio
|
||||
|
typeof(AbpOssManagementFileSystemModule), |
||||
|
// typeof(AbpOssManagementImagingModule),
|
||||
|
typeof(AbpOssManagementDomainModule), |
||||
|
typeof(AbpOssManagementApplicationModule), |
||||
|
typeof(AbpOssManagementHttpApiModule), |
||||
|
typeof(AbpOssManagementSettingManagementModule), |
||||
|
typeof(AbpImagingImageSharpModule), |
||||
|
|
||||
|
typeof(PlatformDomainModule), |
||||
|
typeof(PlatformApplicationModule), |
||||
|
typeof(PlatformHttpApiModule), |
||||
|
typeof(PlatformEntityFrameworkCoreModule), |
||||
|
typeof(PlatformSettingsVueVbenAdminModule), |
||||
|
typeof(PlatformThemeVueVbenAdminModule), |
||||
|
typeof(AbpUINavigationVueVbenAdminModule), |
||||
|
|
||||
|
typeof(AbpSaasDomainModule), |
||||
|
typeof(AbpSaasApplicationModule), |
||||
|
typeof(AbpSaasHttpApiModule), |
||||
|
typeof(AbpSaasEntityFrameworkCoreModule), |
||||
|
|
||||
|
typeof(TaskManagementDomainModule), |
||||
|
typeof(TaskManagementApplicationModule), |
||||
|
typeof(TaskManagementHttpApiModule), |
||||
|
typeof(TaskManagementEntityFrameworkCoreModule), |
||||
|
|
||||
|
typeof(AbpTextTemplatingDomainModule), |
||||
|
typeof(AbpTextTemplatingApplicationModule), |
||||
|
typeof(AbpTextTemplatingHttpApiModule), |
||||
|
typeof(AbpTextTemplatingEntityFrameworkCoreModule), |
||||
|
|
||||
|
typeof(AbpWebhooksModule), |
||||
|
typeof(AbpWebhooksEventBusModule), |
||||
|
typeof(AbpWebhooksIdentityModule), |
||||
|
typeof(AbpWebhooksSaasModule), |
||||
|
typeof(WebhooksManagementDomainModule), |
||||
|
typeof(WebhooksManagementApplicationModule), |
||||
|
typeof(WebhooksManagementHttpApiModule), |
||||
|
typeof(WebhooksManagementEntityFrameworkCoreModule), |
||||
|
|
||||
|
typeof(AbpFeatureManagementApplicationModule), |
||||
|
typeof(AbpFeatureManagementHttpApiModule), |
||||
|
typeof(AbpFeatureManagementEntityFrameworkCoreModule), |
||||
|
|
||||
|
typeof(AbpSettingManagementDomainModule), |
||||
|
typeof(AbpSettingManagementApplicationModule), |
||||
|
typeof(AbpSettingManagementHttpApiModule), |
||||
|
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
||||
|
|
||||
|
typeof(AbpPermissionManagementApplicationModule), |
||||
|
typeof(AbpPermissionManagementHttpApiModule), |
||||
|
typeof(AbpPermissionManagementDomainIdentityModule), |
||||
|
typeof(AbpPermissionManagementDomainOpenIddictModule), |
||||
|
// typeof(AbpPermissionManagementDomainIdentityServerModule),
|
||||
|
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
||||
|
typeof(AbpPermissionManagementDomainOrganizationUnitsModule), // 组织机构权限管理
|
||||
|
|
||||
|
typeof(AbpEntityFrameworkCorePostgreSqlModule), |
||||
|
// typeof(AbpEntityFrameworkCoreMySQLModule),
|
||||
|
|
||||
|
typeof(AbpAliyunSmsModule), |
||||
|
typeof(AbpAliyunSettingManagementModule), |
||||
|
|
||||
|
typeof(AbpAuthenticationQQModule), |
||||
|
typeof(AbpAuthenticationWeChatModule), |
||||
|
typeof(AbpAuthorizationOrganizationUnitsModule), |
||||
|
typeof(AbpIdentityOrganizaztionUnitsModule), |
||||
|
|
||||
|
typeof(AbpBackgroundTasksModule), |
||||
|
typeof(AbpBackgroundTasksActivitiesModule), |
||||
|
typeof(AbpBackgroundTasksDistributedLockingModule), |
||||
|
typeof(AbpBackgroundTasksEventBusModule), |
||||
|
typeof(AbpBackgroundTasksExceptionHandlingModule), |
||||
|
typeof(AbpBackgroundTasksJobsModule), |
||||
|
typeof(AbpBackgroundTasksNotificationsModule), |
||||
|
typeof(AbpBackgroundTasksQuartzModule), |
||||
|
|
||||
|
typeof(AbpDataProtectionManagementApplicationModule), |
||||
|
typeof(AbpDataProtectionManagementHttpApiModule), |
||||
|
typeof(AbpDataProtectionManagementEntityFrameworkCoreModule), |
||||
|
|
||||
|
// typeof(AbpDemoApplicationModule),
|
||||
|
// typeof(AbpDemoHttpApiModule),
|
||||
|
// typeof(AbpDemoEntityFrameworkCoreModule),
|
||||
|
|
||||
|
typeof(AbpDaprClientModule), |
||||
|
typeof(AbpExceptionHandlingModule), |
||||
|
typeof(AbpEmailingExceptionHandlingModule), |
||||
|
typeof(AbpFeaturesLimitValidationModule), |
||||
|
typeof(AbpFeaturesValidationRedisClientModule), |
||||
|
typeof(AbpAspNetCoreMvcLocalizationModule), |
||||
|
|
||||
|
typeof(AbpLocalizationCultureMapModule), |
||||
|
typeof(AbpLocalizationPersistenceModule), |
||||
|
|
||||
|
typeof(AbpOpenApiAuthorizationModule), |
||||
|
|
||||
|
typeof(AbpIMSignalRModule), |
||||
|
|
||||
|
typeof(AbpNotificationsModule), |
||||
|
typeof(AbpNotificationsCommonModule), |
||||
|
typeof(AbpNotificationsSignalRModule), |
||||
|
typeof(AbpNotificationsEmailingModule), |
||||
|
typeof(AbpMultiTenancyEditionsModule), |
||||
|
|
||||
|
typeof(AbpTencentQQModule), |
||||
|
typeof(AbpTencentCloudSettingManagementModule), |
||||
|
|
||||
|
typeof(AbpIdentityWeChatModule), |
||||
|
typeof(AbpNotificationsWeChatMiniProgramModule), |
||||
|
typeof(AbpWeChatMiniProgramModule), |
||||
|
typeof(AbpWeChatOfficialModule), |
||||
|
typeof(AbpWeChatOfficialApplicationModule), |
||||
|
typeof(AbpWeChatOfficialHttpApiModule), |
||||
|
typeof(AbpWeChatWorkModule), |
||||
|
typeof(AbpWeChatWorkApplicationModule), |
||||
|
typeof(AbpWeChatWorkHttpApiModule), |
||||
|
typeof(AbpWeChatOfficialHandlersModule), |
||||
|
typeof(AbpWeChatWorkHandlersModule), |
||||
|
typeof(AbpWeChatSettingManagementModule), |
||||
|
|
||||
|
typeof(AbpDataDbMigratorModule), |
||||
|
typeof(AbpIdGeneratorModule), |
||||
|
typeof(AbpUINavigationModule), |
||||
|
typeof(AbpAccountTemplatesModule), |
||||
|
typeof(AbpAspNetCoreAuthenticationJwtBearerModule), |
||||
|
typeof(AbpCachingStackExchangeRedisModule), |
||||
|
// typeof(AbpElsaModule),
|
||||
|
// typeof(AbpElsaServerModule),
|
||||
|
// typeof(AbpElsaActivitiesModule),
|
||||
|
// typeof(AbpElsaEntityFrameworkCoreModule),
|
||||
|
// typeof(AbpElsaEntityFrameworkCorePostgreSqlModule),
|
||||
|
// typeof(AbpElsaModule),
|
||||
|
// typeof(AbpElsaServerModule),
|
||||
|
// typeof(AbpElsaActivitiesModule),
|
||||
|
// typeof(AbpElsaEntityFrameworkCoreModule),
|
||||
|
// typeof(AbpElsaEntityFrameworkCoreMySqlModule),
|
||||
|
|
||||
|
typeof(AbpExporterMiniExcelModule), |
||||
|
typeof(AbpAspNetCoreMvcUiMultiTenancyModule), |
||||
|
typeof(AbpAspNetCoreSerilogModule), |
||||
|
typeof(AbpHttpClientWrapperModule), |
||||
|
typeof(AbpAspNetCoreMvcWrapperModule), |
||||
|
typeof(AbpAspNetCoreMvcIdempotentWrapperModule), |
||||
|
typeof(AbpAspNetCoreHttpOverridesModule), |
||||
|
typeof(AbpAspNetCoreMvcUiBasicThemeModule), |
||||
|
typeof(AbpEventBusModule), |
||||
|
typeof(AbpAutofacModule) |
||||
|
)] |
||||
|
public partial class MicroServiceApplicationsSingleModule : AbpModule |
||||
|
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
||||
|
|
||||
|
PreConfigureWrapper(); |
||||
|
PreConfigureFeature(); |
||||
|
PreConfigureIdentity(); |
||||
|
PreConfigureApp(configuration); |
||||
|
PreConfigureQuartz(configuration); |
||||
|
PreConfigureAuthServer(configuration); |
||||
|
PreConfigureElsa(context.Services, configuration); |
||||
|
PreConfigureCertificate(configuration, hostingEnvironment); |
||||
|
} |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
|
||||
|
ConfigureWeChat(); |
||||
|
ConfigureWrapper(); |
||||
|
ConfigureExporter(); |
||||
|
ConfigureAuditing(); |
||||
|
ConfigureDbContext(); |
||||
|
ConfigureIdempotent(); |
||||
|
ConfigureMvcUiTheme(); |
||||
|
ConfigureDataSeeder(); |
||||
|
ConfigureLocalization(); |
||||
|
ConfigureKestrelServer(); |
||||
|
ConfigureBackgroundTasks(); |
||||
|
ConfigureExceptionHandling(); |
||||
|
ConfigureVirtualFileSystem(); |
||||
|
ConfigureEntityDataProtected(); |
||||
|
ConfigureUrls(configuration); |
||||
|
ConfigureCaching(configuration); |
||||
|
ConfigureAuditing(configuration); |
||||
|
ConfigureIdentity(configuration); |
||||
|
ConfigureAuthServer(configuration); |
||||
|
ConfigureSwagger(context.Services); |
||||
|
ConfigureEndpoints(context.Services); |
||||
|
ConfigureBlobStoring(configuration); |
||||
|
ConfigureMultiTenancy(configuration); |
||||
|
ConfigureJsonSerializer(configuration); |
||||
|
ConfigureTextTemplating(configuration); |
||||
|
ConfigureFeatureManagement(configuration); |
||||
|
ConfigureSettingManagement(configuration); |
||||
|
ConfigureWebhooksManagement(configuration); |
||||
|
ConfigurePermissionManagement(configuration); |
||||
|
ConfigureNotificationManagement(configuration); |
||||
|
ConfigureCors(context.Services, configuration); |
||||
|
ConfigureDistributedLock(context.Services, configuration); |
||||
|
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); |
||||
|
} |
||||
|
|
||||
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
||||
|
{ |
||||
|
AsyncHelper.RunSync(async () => await OnApplicationInitializationAsync(context)); |
||||
|
} |
||||
|
|
||||
|
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) |
||||
|
{ |
||||
|
await context.ServiceProvider.GetRequiredService<IDataSeeder>().SeedAsync(); ; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
namespace LY.AIO.Applications.Single.Microsoft.Extensions.DependencyInjection |
||||
|
{ |
||||
|
public static class SameSiteCookiesServiceCollectionExtensions |
||||
|
{ |
||||
|
public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services) |
||||
|
{ |
||||
|
services.Configure<CookiePolicyOptions>(options => |
||||
|
{ |
||||
|
options.MinimumSameSitePolicy = SameSiteMode.Unspecified; |
||||
|
options.OnAppendCookie = cookieContext => |
||||
|
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); |
||||
|
options.OnDeleteCookie = cookieContext => |
||||
|
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); |
||||
|
}); |
||||
|
|
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
private static void CheckSameSite(HttpContext httpContext, CookieOptions options) |
||||
|
{ |
||||
|
if (options.SameSite == SameSiteMode.None) |
||||
|
{ |
||||
|
var userAgent = httpContext.Request.Headers["User-Agent"].ToString(); |
||||
|
if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent)) |
||||
|
{ |
||||
|
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
|
||||
|
options.SameSite = SameSiteMode.Unspecified; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static bool DisallowsSameSiteNone(string userAgent) |
||||
|
{ |
||||
|
// Cover all iOS based browsers here. This includes:
|
||||
|
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
|
||||
|
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
|
||||
|
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
|
||||
|
// All of which are broken by SameSite=None, because they use the iOS networking stack
|
||||
|
if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12")) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
|
||||
|
// - Safari on Mac OS X.
|
||||
|
// This does not include:
|
||||
|
// - Chrome on Mac OS X
|
||||
|
// Because they do not use the Mac OS networking stack.
|
||||
|
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") && |
||||
|
userAgent.Contains("Version/") && userAgent.Contains("Safari")) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
|
||||
|
// and none in this range require it.
|
||||
|
// Note: this covers some pre-Chromium Edge versions,
|
||||
|
// but pre-Chromium Edge does not require SameSite=None.
|
||||
|
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6")) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.MultiTenancy; |
||||
|
|
||||
|
public interface ITenantConfigurationCache |
||||
|
{ |
||||
|
Task RefreshAsync(); |
||||
|
|
||||
|
Task<List<TenantConfiguration>> GetTenantsAsync(); |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using LINGYUN.Abp.Saas.Tenants; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.MultiTenancy; |
||||
|
|
||||
|
public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency |
||||
|
{ |
||||
|
protected ITenantRepository TenantRepository { get; } |
||||
|
protected IDistributedCache<TenantConfigurationCacheItem> TenantCache { get; } |
||||
|
|
||||
|
public TenantConfigurationCache( |
||||
|
ITenantRepository tenantRepository, |
||||
|
IDistributedCache<TenantConfigurationCacheItem> tenantCache) |
||||
|
{ |
||||
|
TenantRepository = tenantRepository; |
||||
|
TenantCache = tenantCache; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task RefreshAsync() |
||||
|
{ |
||||
|
var cacheKey = GetCacheKey(); |
||||
|
|
||||
|
await TenantCache.RemoveAsync(cacheKey); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<List<TenantConfiguration>> GetTenantsAsync() |
||||
|
{ |
||||
|
return (await GetForCacheItemAsync()).Tenants; |
||||
|
} |
||||
|
|
||||
|
protected async virtual Task<TenantConfigurationCacheItem> GetForCacheItemAsync() |
||||
|
{ |
||||
|
var cacheKey = GetCacheKey(); |
||||
|
var cacheItem = await TenantCache.GetAsync(cacheKey); |
||||
|
if (cacheItem == null) |
||||
|
{ |
||||
|
var allActiveTenants = await TenantRepository.GetListAsync(); |
||||
|
|
||||
|
cacheItem = new TenantConfigurationCacheItem( |
||||
|
allActiveTenants |
||||
|
.Where(t => t.IsActive) |
||||
|
.Select(t => new TenantConfiguration(t.Id, t.Name) |
||||
|
{ |
||||
|
IsActive = t.IsActive, |
||||
|
}).ToList()); |
||||
|
|
||||
|
await TenantCache.SetAsync(cacheKey, cacheItem); |
||||
|
} |
||||
|
|
||||
|
return cacheItem; |
||||
|
} |
||||
|
|
||||
|
protected virtual string GetCacheKey() |
||||
|
{ |
||||
|
return "_Abp_Tenant_Configuration"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.MultiTenancy; |
||||
|
|
||||
|
[IgnoreMultiTenancy] |
||||
|
public class TenantConfigurationCacheItem |
||||
|
{ |
||||
|
public List<TenantConfiguration> Tenants { get; set; } |
||||
|
|
||||
|
public TenantConfigurationCacheItem() |
||||
|
{ |
||||
|
Tenants = new List<TenantConfiguration>(); |
||||
|
} |
||||
|
|
||||
|
public TenantConfigurationCacheItem(List<TenantConfiguration> tenants) |
||||
|
{ |
||||
|
Tenants = tenants; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,103 @@ |
|||||
|
@using Volo.Abp.Account.Localization |
||||
|
@using Volo.Abp.Users |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Microsoft.Extensions.Localization |
||||
|
@using Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Theming |
||||
|
@using Volo.Abp.Data |
||||
|
@using Volo.Abp.Identity.Settings |
||||
|
@using Volo.Abp.Localization |
||||
|
@using Volo.Abp.Settings |
||||
|
@using Volo.Abp.ObjectExtending |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
@inject ICurrentUser CurrentUser |
||||
|
@inject ISettingProvider SettingManager |
||||
|
@inject IThemeManager ThemeManager |
||||
|
@inject IStringLocalizerFactory StringLocalizerFactory |
||||
|
@model Volo.Abp.Account.Web.Pages.Account.Components.ProfileManagementGroup.PersonalInfo.AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel |
||||
|
@{ |
||||
|
var isUserNameUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled), "true", |
||||
|
StringComparison.OrdinalIgnoreCase); |
||||
|
|
||||
|
var isEmailUpdateEnabled = string.Equals(await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled), "true", |
||||
|
StringComparison.OrdinalIgnoreCase); |
||||
|
} |
||||
|
|
||||
|
<h4>@L["PersonalSettings"]</h4><hr/> |
||||
|
<form method="post" id="PersonalSettingsForm"> |
||||
|
|
||||
|
<input asp-for="ConcurrencyStamp" /> |
||||
|
|
||||
|
<abp-input asp-for="UserName" readonly="!isUserNameUpdateEnabled"/> |
||||
|
|
||||
|
<abp-row> |
||||
|
<abp-column size-md="_6"> |
||||
|
<abp-input asp-for="Name"/> |
||||
|
</abp-column> |
||||
|
<abp-column size-md="_6"> |
||||
|
<abp-input asp-for="Surname"/> |
||||
|
</abp-column> |
||||
|
</abp-row> |
||||
|
|
||||
|
<abp-row> |
||||
|
<abp-column size-md="_9"> |
||||
|
<abp-input asp-for="Email" readonly="!isEmailUpdateEnabled"/> |
||||
|
</abp-column> |
||||
|
<abp-column size-md="_3"> |
||||
|
@if (CurrentUser.EmailVerified) |
||||
|
{ |
||||
|
<abp-button button-type="Success" text="@L["Confirmed"].Value"/> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
@*<abp-button href="/Account/SendEmailConfirm" button-type="Link" text="@L["Validation"].Value" />*@ |
||||
|
<a href="/Account/SendEmailConfirm">@L["Validation"].Value</a> |
||||
|
} |
||||
|
</abp-column> |
||||
|
</abp-row> |
||||
|
|
||||
|
<abp-input asp-for="PhoneNumber"/> |
||||
|
|
||||
|
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<AccountProfilePersonalInfoManagementGroupViewComponent.PersonalInfoModel>()) |
||||
|
{ |
||||
|
var isAllowed = propertyInfo.Configuration.GetOrDefault(IdentityModuleExtensionConsts.ConfigurationNames.AllowUserToEdit); |
||||
|
|
||||
|
if (isAllowed == null || !isAllowed.Equals(true)) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (!propertyInfo.Name.EndsWith("_Text")) |
||||
|
{ |
||||
|
if (propertyInfo.Type.IsEnum || !propertyInfo.Lookup.Url.IsNullOrEmpty()) |
||||
|
{ |
||||
|
if (propertyInfo.Type.IsEnum) |
||||
|
{ |
||||
|
Model.ExtraProperties.ToEnum(propertyInfo.Name, propertyInfo.Type); |
||||
|
} |
||||
|
<abp-select asp-for="ExtraProperties[propertyInfo.Name]" |
||||
|
name="ExtraProperties.@propertyInfo.Name" |
||||
|
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)" |
||||
|
autocomplete-api-url="@propertyInfo.Lookup.Url" |
||||
|
autocomplete-selected-item-name="@Model.GetProperty(propertyInfo.Name + "_Text")" |
||||
|
autocomplete-selected-item-value="@Model.GetProperty(propertyInfo.Name)" |
||||
|
autocomplete-filter-param-name="@propertyInfo.Lookup.FilterParamName" |
||||
|
autocomplete-items-property-name="@propertyInfo.Lookup.ResultListPropertyName" |
||||
|
autocomplete-display-property-name="@propertyInfo.Lookup.DisplayPropertyName" |
||||
|
autocomplete-value-property-name="@propertyInfo.Lookup.ValuePropertyName"> |
||||
|
</abp-select> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<abp-input type="@propertyInfo.GetInputType()" |
||||
|
asp-for="ExtraProperties[propertyInfo.Name]" |
||||
|
name="ExtraProperties.@propertyInfo.Name" |
||||
|
label="@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)" |
||||
|
asp-format="@propertyInfo.GetInputFormatOrNull()" |
||||
|
value="@propertyInfo.GetInputValueOrNull(Model.GetProperty(propertyInfo.Name))" /> |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/> |
||||
|
</form> |
||||
@ -0,0 +1,28 @@ |
|||||
|
(function ($) { |
||||
|
$(function () { |
||||
|
var l = abp.localization.getResource("AbpAccount"); |
||||
|
|
||||
|
$('#PersonalSettingsForm').submit(function (e) { |
||||
|
e.preventDefault(); |
||||
|
|
||||
|
if (!$('#PersonalSettingsForm').valid()) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var input = $('#PersonalSettingsForm').serializeFormToObject(); |
||||
|
|
||||
|
volo.abp.account.profile.update(input).then(function (result) { |
||||
|
abp.notify.success(l('PersonalSettingsSaved')); |
||||
|
updateConcurrencyStamp(); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
abp.event.on('passwordChanged', updateConcurrencyStamp); |
||||
|
|
||||
|
function updateConcurrencyStamp(){ |
||||
|
volo.abp.account.profile.get().then(function(profile){ |
||||
|
$("#ConcurrencyStamp").val(profile.concurrencyStamp); |
||||
|
}); |
||||
|
} |
||||
|
})(jQuery); |
||||
@ -0,0 +1,17 @@ |
|||||
|
@page |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.Account.Localization |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.EmailConfirmModel |
||||
|
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout |
||||
|
<div class="card mt-3 shadow-sm rounded"> |
||||
|
<div class="card-body p-5"> |
||||
|
<h4>@L["EmailConfirm"]</h4> |
||||
|
<form method="post"> |
||||
|
<abp-input asp-for="UserId"/> |
||||
|
<abp-input asp-for="ConfirmToken"/> |
||||
|
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a> |
||||
|
<abp-button type="submit" button-type="Primary" text="@L["Submit"].Value"/> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,72 @@ |
|||||
|
using LINGYUN.Abp.Account; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using Volo.Abp.Account.Localization; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.Validation; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
public class EmailConfirmModel : AccountPageModel |
||||
|
{ |
||||
|
[Required] |
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public Guid UserId { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ConfirmToken { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrl { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrlHash { get; set; } |
||||
|
|
||||
|
public IMyProfileAppService MyProfileAppService { get; set; } |
||||
|
|
||||
|
public EmailConfirmModel() |
||||
|
{ |
||||
|
LocalizationResourceType = typeof(AccountResource); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
ValidateModel(); |
||||
|
|
||||
|
await MyProfileAppService.ConfirmEmailAsync( |
||||
|
new ConfirmEmailInput |
||||
|
{ |
||||
|
ConfirmToken = ConfirmToken, |
||||
|
}); |
||||
|
} |
||||
|
catch (AbpIdentityResultException e) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(e.Message)) |
||||
|
{ |
||||
|
Alerts.Warning(GetLocalizeExceptionMessage(e)); |
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
catch (AbpValidationException) |
||||
|
{ |
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
return RedirectToPage("./ConfirmEmailConfirmation", new |
||||
|
{ |
||||
|
returnUrl = ReturnUrl, |
||||
|
returnUrlHash = ReturnUrlHash |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
@page |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.EmailConfirmConfirmationModel |
||||
|
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.Account.Localization |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
<div class="card mt-3 shadow-sm rounded"> |
||||
|
<div class="card-body p-5"> |
||||
|
<h4>@L["EmailConfirm"]</h4> |
||||
|
<p>@L["YourEmailIsSuccessfullyConfirm"]</p> |
||||
|
<a abp-button="Primary" href="@Url.Content(Model.ReturnUrl)">@L["GoToTheApplication"]</a> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,22 @@ |
|||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account; |
||||
|
|
||||
|
[AllowAnonymous] |
||||
|
public class EmailConfirmConfirmationModel : AccountPageModel |
||||
|
{ |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrl { get; set; } |
||||
|
|
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrlHash { get; set; } |
||||
|
|
||||
|
public async virtual Task<IActionResult> OnGetAsync() |
||||
|
{ |
||||
|
ReturnUrl = await GetRedirectUrlAsync(ReturnUrl, ReturnUrlHash); |
||||
|
|
||||
|
return Page(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
@page |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.Account.Localization |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.SendCodeModel |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
|
||||
|
<div class="card mt-3 shadow-sm rounded"> |
||||
|
<div class="card-body p-5"> |
||||
|
<h4>@L["TwoFactor"]</h4> |
||||
|
<form method="post" class="mt-4"> |
||||
|
<abp-input asp-for="RememberMe" /> |
||||
|
<input asp-for="ReturnUrl" /> |
||||
|
<input asp-for="ReturnUrlHash" /> |
||||
|
<div class="form-group"> |
||||
|
<abp-select asp-for="Input.SelectedProvider" label="@L["SelectedProvider"].Value" asp-items="@Model.Providers"></abp-select> |
||||
|
</div> |
||||
|
<div class="d-grid gap-2"> |
||||
|
<abp-button type="submit" button-type="Primary" class="mt-2 mb-3">@L["SendVerifyCode"]</abp-button> |
||||
|
</div> |
||||
|
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})"> |
||||
|
<i class="fa fa-long-arrow-left"></i> @L["Login"] |
||||
|
</a> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
@ -0,0 +1,125 @@ |
|||||
|
using LINGYUN.Abp.Account.Emailing; |
||||
|
using LINGYUN.Abp.Identity.Settings; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Rendering; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Account.Localization; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
using Volo.Abp.Sms; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
public class SendCodeModel : AccountPageModel |
||||
|
{ |
||||
|
[BindProperty] |
||||
|
public SendCodeInputModel Input { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrl { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrlHash { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public bool RememberMe { get; set; } |
||||
|
|
||||
|
public IEnumerable<SelectListItem> Providers { get; set; } |
||||
|
|
||||
|
protected ISmsSender SmsSender { get; } |
||||
|
|
||||
|
protected IAccountEmailVerifySender AccountEmailVerifySender { get; } |
||||
|
|
||||
|
public SendCodeModel( |
||||
|
ISmsSender smsSender, |
||||
|
IAccountEmailVerifySender accountEmailVerifySender) |
||||
|
{ |
||||
|
SmsSender = smsSender; |
||||
|
AccountEmailVerifySender = accountEmailVerifySender; |
||||
|
|
||||
|
LocalizationResourceType = typeof(AccountResource); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IActionResult> OnGetAsync() |
||||
|
{ |
||||
|
Input = new SendCodeInputModel(); |
||||
|
|
||||
|
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); |
||||
|
if (user == null) |
||||
|
{ |
||||
|
// ˫������Ϣ��֤ʧ��,һ�㶼�dz�ʱ�˻����û���Ϣ���
|
||||
|
Alerts.Warning(L["TwoFactorAuthenticationInvaidUser"]); |
||||
|
return Page(); |
||||
|
} |
||||
|
var userFactors = await UserManager.GetValidTwoFactorProvidersAsync(user); |
||||
|
Providers = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList(); |
||||
|
|
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); |
||||
|
if (user == null) |
||||
|
{ |
||||
|
Alerts.Warning(L["TwoFactorAuthenticationInvaidUser"]); |
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
if (Input.SelectedProvider == "Authenticator") |
||||
|
{ |
||||
|
// �û�ͨ���ʼ�/�������ӽ�����Ȩҳ��
|
||||
|
return RedirectToPage("VerifyAuthenticatorCode", new |
||||
|
{ |
||||
|
returnUrl = ReturnUrl, |
||||
|
returnUrlHash = ReturnUrlHash, |
||||
|
rememberMe = RememberMe |
||||
|
}); |
||||
|
} |
||||
|
// ������֤��
|
||||
|
var code = await UserManager.GenerateTwoFactorTokenAsync(user, Input.SelectedProvider); |
||||
|
if (string.IsNullOrWhiteSpace(code)) |
||||
|
{ |
||||
|
Alerts.Warning(L["InvaidGenerateTwoFactorToken"]); |
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
if (Input.SelectedProvider == "Email") |
||||
|
{ |
||||
|
await AccountEmailVerifySender |
||||
|
.SendMailLoginVerifyCodeAsync( |
||||
|
code, |
||||
|
user.UserName, |
||||
|
user.Email); |
||||
|
} |
||||
|
else if (Input.SelectedProvider == "Phone") |
||||
|
{ |
||||
|
var phoneNumber = await UserManager.GetPhoneNumberAsync(user); |
||||
|
var templateCode = await SettingProvider.GetOrNullAsync(IdentitySettingNames.User.SmsUserSignin); |
||||
|
Check.NotNullOrWhiteSpace(templateCode, nameof(IdentitySettingNames.User.SmsUserSignin)); |
||||
|
|
||||
|
// TODO: �Ժ���չ����ģ�巢��
|
||||
|
var smsMessage = new SmsMessage(phoneNumber, code); |
||||
|
smsMessage.Properties.Add("code", code); |
||||
|
smsMessage.Properties.Add("TemplateCode", templateCode); |
||||
|
|
||||
|
await SmsSender.SendAsync(smsMessage); |
||||
|
} |
||||
|
|
||||
|
return RedirectToPage("VerifyCode", new |
||||
|
{ |
||||
|
provider = Input.SelectedProvider, |
||||
|
returnUrl = ReturnUrl, |
||||
|
returnUrlHash = ReturnUrlHash, |
||||
|
rememberMe = RememberMe |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class SendCodeInputModel |
||||
|
{ |
||||
|
public string SelectedProvider { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
@page |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.Account.Localization |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.SendEmailConfirmModel |
||||
|
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout |
||||
|
<div class="card mt-3 shadow-sm rounded"> |
||||
|
<div class="card-body p-5"> |
||||
|
<h4>@L["EmailConfirm"]</h4> |
||||
|
<form method="post"> |
||||
|
<abp-input asp-for="Email" readonly="true" /> |
||||
|
<a abp-button="Secondary" asp-page="./Login">@L["Cancel"]</a> |
||||
|
<abp-button type="submit" button-type="Primary" text="@L["ClickToValidation"].Value"/> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,73 @@ |
|||||
|
using LINGYUN.Abp.Account; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.Account.Localization; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.Validation; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
public class SendEmailConfirmModel : AccountPageModel |
||||
|
{ |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string Email { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrl { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrlHash { get; set; } |
||||
|
|
||||
|
public IMyProfileAppService MyProfileAppService { get; set; } |
||||
|
|
||||
|
public SendEmailConfirmModel() |
||||
|
{ |
||||
|
LocalizationResourceType = typeof(AccountResource); |
||||
|
} |
||||
|
|
||||
|
public virtual Task<IActionResult> OnGetAsync() |
||||
|
{ |
||||
|
Email = CurrentUser.Email; |
||||
|
|
||||
|
return Task.FromResult<IActionResult>(Page()); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
ValidateModel(); |
||||
|
|
||||
|
await MyProfileAppService.SendEmailConfirmLinkAsync( |
||||
|
new SendEmailConfirmCodeDto |
||||
|
{ |
||||
|
Email = Email, |
||||
|
AppName = "MVC", |
||||
|
ReturnUrl = ReturnUrl, |
||||
|
ReturnUrlHash = ReturnUrlHash |
||||
|
}); |
||||
|
} |
||||
|
catch (AbpIdentityResultException e) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(e.Message)) |
||||
|
{ |
||||
|
Alerts.Warning(GetLocalizeExceptionMessage(e)); |
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
catch (AbpValidationException) |
||||
|
{ |
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
return RedirectToPage("~/Account/Manage", new |
||||
|
{ |
||||
|
returnUrl = ReturnUrl |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
using Microsoft.AspNetCore.Authentication; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.Account.Web; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.OpenIddict; |
||||
|
using IdentityOptions = Microsoft.AspNetCore.Identity.IdentityOptions; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 重写登录模型,实现双因素登录
|
||||
|
/// </summary>
|
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
[ExposeServices(typeof(LoginModel), typeof(OpenIddictSupportedLoginModel))] |
||||
|
public class TwoFactorSupportedLoginModel : OpenIddictSupportedLoginModel |
||||
|
{ |
||||
|
public TwoFactorSupportedLoginModel( |
||||
|
IAuthenticationSchemeProvider schemeProvider, |
||||
|
IOptions<AbpAccountOptions> accountOptions, |
||||
|
IOptions<IdentityOptions> identityOptions, |
||||
|
IdentityDynamicClaimsPrincipalContributorCache identityDynamicClaimsPrincipalContributorCache, |
||||
|
AbpOpenIddictRequestHelper openIddictRequestHelper) |
||||
|
: base(schemeProvider, accountOptions, identityOptions, identityDynamicClaimsPrincipalContributorCache, openIddictRequestHelper) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected async override Task<List<ExternalProviderModel>> GetExternalProviders() |
||||
|
{ |
||||
|
var providers = await base.GetExternalProviders(); |
||||
|
|
||||
|
foreach (var provider in providers) |
||||
|
{ |
||||
|
var localizedDisplayName = L[provider.DisplayName]; |
||||
|
if (localizedDisplayName.ResourceNotFound) |
||||
|
{ |
||||
|
localizedDisplayName = L["AuthenticationScheme:" + provider.DisplayName]; |
||||
|
} |
||||
|
|
||||
|
if (!localizedDisplayName.ResourceNotFound) |
||||
|
{ |
||||
|
provider.DisplayName = localizedDisplayName.Value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return providers; |
||||
|
} |
||||
|
|
||||
|
protected override Task<IActionResult> TwoFactorLoginResultAsync() |
||||
|
{ |
||||
|
// 重定向双因素认证页面
|
||||
|
return Task.FromResult<IActionResult>(RedirectToPage("SendCode", new |
||||
|
{ |
||||
|
returnUrl = ReturnUrl, |
||||
|
returnUrlHash = ReturnUrlHash, |
||||
|
rememberMe = LoginInput.RememberMe |
||||
|
})); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
@page |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.UseRecoveryCodeModel |
||||
|
@{ |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.RazorPages; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
public class UseRecoveryCodeModel : PageModel |
||||
|
{ |
||||
|
public void OnGet() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
@page |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.Account.Localization |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.VerifyAuthenticatorCodeModel |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
<div class="card mt-3 shadow-sm rounded"> |
||||
|
<div class="card-body p-5"> |
||||
|
<form method="post" class="mt-4"> |
||||
|
<input asp-for="RememberMe" /> |
||||
|
<input asp-for="ReturnUrlHash" /> |
||||
|
<div class="form-group"> |
||||
|
<label asp-for="Input.VerifyCode"></label> |
||||
|
<input asp-for="Input.VerifyCode" class="form-control" /> |
||||
|
<span asp-validation-for="Input.VerifyCode" class="text-danger"></span> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label asp-for="RememberBrowser"></label> |
||||
|
<abp-input asp-for="RememberBrowser" /> |
||||
|
</div> |
||||
|
<abp-button type="submit" button-type="Primary" class="btn-block btn-lg mt-3">@L["VerifyAuthenticatorCode"]</abp-button> |
||||
|
<a asp-page="./Login" asp-all-route-data="@(new Dictionary<string, string> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})"> |
||||
|
<i class="fa fa-long-arrow-left"></i> @L["Login"] |
||||
|
</a> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,59 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
public class VerifyAuthenticatorCodeModel : AccountPageModel |
||||
|
{ |
||||
|
[BindProperty] |
||||
|
public VerifyAuthenticatorCodeInputModel Input { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrl { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrlHash { get; set; } |
||||
|
|
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public bool RememberBrowser { get; set; } |
||||
|
|
||||
|
[HiddenInput] |
||||
|
public bool RememberMe { get; set; } |
||||
|
|
||||
|
public virtual IActionResult OnGet() |
||||
|
{ |
||||
|
Input = new VerifyAuthenticatorCodeInputModel(); |
||||
|
|
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
var result = await SignInManager.TwoFactorAuthenticatorSignInAsync(Input.VerifyCode, RememberMe, RememberBrowser); |
||||
|
if (result.Succeeded) |
||||
|
{ |
||||
|
return await RedirectSafelyAsync(ReturnUrl, ReturnUrlHash); |
||||
|
} |
||||
|
if (result.IsLockedOut) |
||||
|
{ |
||||
|
Logger.LogWarning(7, "User account locked out."); |
||||
|
Alerts.Warning(L["UserLockedOutMessage"]); |
||||
|
return Page(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Alerts.Danger(L["TwoFactorAuthenticationInvaidUser"]);// TODO: ����״̬��Ľ��
|
||||
|
return Page(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class VerifyAuthenticatorCodeInputModel |
||||
|
{ |
||||
|
[Required] |
||||
|
public string VerifyCode { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
@page |
||||
|
@inject IHtmlLocalizer<AccountResource> L |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.Account.Localization |
||||
|
@model LY.AIO.Applications.Single.Pages.Account.VerifyCodeModel |
||||
|
<div class="card mt-3 shadow-sm rounded"> |
||||
|
<div class="card-body p-5"> |
||||
|
<form method="post" class="mt-4"> |
||||
|
<input asp-for="Provider" /> |
||||
|
<input asp-for="ReturnUrl" /> |
||||
|
<input asp-for="ReturnUrlHash" /> |
||||
|
<input asp-for="RememberMe" /> |
||||
|
<div class="form-group"> |
||||
|
<abp-input asp-for="Input.VerifyCode" label="@L["VerifyCode"].Value" class="form-control" /> |
||||
|
</div> |
||||
|
<abp-row> |
||||
|
<abp-column> |
||||
|
<abp-input asp-for="Input.RememberBrowser" label="@L["RememberBrowser"].Value" /> |
||||
|
</abp-column> |
||||
|
</abp-row> |
||||
|
<div class="d-grid gap-2"> |
||||
|
<abp-button type="submit" button-type="Primary" class="mt-2 mb-3">@L["VerifyAuthenticatorCode"]</abp-button> |
||||
|
</div> |
||||
|
<a asp-page="./SendCode" asp-all-route-data="@(new Dictionary<string, string> {{"returnUrl", Model.ReturnUrl}, {"returnUrlHash", Model.ReturnUrlHash}})"> |
||||
|
<i class="fa fa-long-arrow-left"></i> @L["ReSendVerifyCode"] |
||||
|
</a> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,90 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using Volo.Abp.Account.Localization; |
||||
|
using Volo.Abp.Account.Web.Pages.Account; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages.Account |
||||
|
{ |
||||
|
public class VerifyCodeModel : AccountPageModel |
||||
|
{ |
||||
|
[BindProperty] |
||||
|
public VerifyCodeInputModel Input { get; set; } |
||||
|
/// <summary>
|
||||
|
/// ˫������֤�ṩ����
|
||||
|
/// </summary>
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string Provider { get; set; } |
||||
|
/// <summary>
|
||||
|
/// �ض���Url
|
||||
|
/// </summary>
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrl { get; set; } |
||||
|
/// <summary>
|
||||
|
///
|
||||
|
/// </summary>
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public string ReturnUrlHash { get; set; } |
||||
|
/// <summary>
|
||||
|
/// �Ƿ��ס��¼״̬
|
||||
|
/// </summary>
|
||||
|
[HiddenInput] |
||||
|
[BindProperty(SupportsGet = true)] |
||||
|
public bool RememberMe { get; set; } |
||||
|
|
||||
|
public VerifyCodeModel() |
||||
|
{ |
||||
|
LocalizationResourceType = typeof(AccountResource); |
||||
|
} |
||||
|
|
||||
|
public virtual IActionResult OnGet() |
||||
|
{ |
||||
|
Input = new VerifyCodeInputModel(); |
||||
|
|
||||
|
return Page(); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<IActionResult> OnPostAsync() |
||||
|
{ |
||||
|
// ��֤�û���¼״̬
|
||||
|
var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); |
||||
|
if (user == null) |
||||
|
{ |
||||
|
Alerts.Warning(L["TwoFactorAuthenticationInvaidUser"]); |
||||
|
return Page(); |
||||
|
} |
||||
|
// ˫���ص�¼
|
||||
|
var result = await SignInManager.TwoFactorSignInAsync(Provider, Input.VerifyCode, RememberMe, Input.RememberBrowser); |
||||
|
if (result.Succeeded) |
||||
|
{ |
||||
|
return await RedirectSafelyAsync(ReturnUrl, ReturnUrlHash); |
||||
|
} |
||||
|
if (result.IsLockedOut) |
||||
|
{ |
||||
|
Logger.LogWarning(7, "User account locked out."); |
||||
|
Alerts.Warning(L["UserLockedOutMessage"]); |
||||
|
return Page(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Alerts.Danger(L["TwoFactorAuthenticationInvaidUser"]);// TODO: ����״̬��Ľ��
|
||||
|
return Page(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class VerifyCodeInputModel |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// �Ƿ���������м�ס��¼״̬
|
||||
|
/// </summary>
|
||||
|
public bool RememberBrowser { get; set; } |
||||
|
/// <summary>
|
||||
|
/// ���͵���֤��
|
||||
|
/// </summary>
|
||||
|
[Required] |
||||
|
public string VerifyCode { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
@page |
||||
|
@using Microsoft.AspNetCore.Mvc.TagHelpers |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Alert |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid |
||||
|
@using Volo.Abp.Users |
||||
|
@model LY.AIO.Applications.Single.Pages.IndexModel |
||||
|
@inject ICurrentUser CurrentUser |
||||
|
@if (CurrentUser.IsAuthenticated) |
||||
|
{ |
||||
|
<div> |
||||
|
<abp-row> |
||||
|
<abp-column size-md="_3" class="text-center"> |
||||
|
<i class="fa fa-user d-block" style="font-size: 10em; color: #12b900"></i> |
||||
|
<a abp-button="Primary" asp-controller="Logout" asp-action="Index" asp-area="Account">Logout</a> |
||||
|
</abp-column> |
||||
|
<abp-column size-md="_9"> |
||||
|
<h2>@CurrentUser.UserName</h2> |
||||
|
<h5 class="text-muted">@CurrentUser.Email</h5> |
||||
|
<div> |
||||
|
<strong>Roles</strong>: @CurrentUser.Roles.JoinAsString(", ") |
||||
|
<br /> |
||||
|
<strong>Claims</strong>: <br /> |
||||
|
@Html.Raw(CurrentUser.GetAllClaims().Select(c => $"{c.Type}={c.Value}").JoinAsString(" <br /> ")) |
||||
|
</div> |
||||
|
</abp-column> |
||||
|
</abp-row> |
||||
|
</div> |
||||
|
} |
||||
|
|
||||
|
@if (!CurrentUser.IsAuthenticated) |
||||
|
{ |
||||
|
<div class="text-center"> |
||||
|
<i class="fa fa-user d-block" style="font-size: 10em; color: #aaa"></i><br/><br /> |
||||
|
<a abp-button="Primary" asp-page="/Account/Login">Login</a> |
||||
|
</div> |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.Pages |
||||
|
{ |
||||
|
public class IndexModel : AbpPageModel |
||||
|
{ |
||||
|
public void OnGet() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
||||
|
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
||||
|
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
||||
|
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
||||
@ -0,0 +1,82 @@ |
|||||
|
using LINGYUN.Abp.Identity.Session.AspNetCore; |
||||
|
using LY.AIO.Applications.Single; |
||||
|
using Microsoft.AspNetCore.Cors; |
||||
|
using Serilog; |
||||
|
using Volo.Abp.IO; |
||||
|
using Volo.Abp.Modularity.PlugIns; |
||||
|
|
||||
|
var builder = WebApplication.CreateBuilder(args); |
||||
|
builder.Services.AddCors(options => |
||||
|
{ |
||||
|
options.AddDefaultPolicy(policy => |
||||
|
{ |
||||
|
policy |
||||
|
.WithOrigins( |
||||
|
builder.Configuration["App:CorsOrigins"] |
||||
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
||||
|
.Select(o => o.RemovePostFix("/")) |
||||
|
.ToArray() |
||||
|
) |
||||
|
.WithAbpExposedHeaders() |
||||
|
.WithAbpWrapExposedHeaders() |
||||
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
||||
|
.AllowAnyHeader() |
||||
|
.AllowAnyMethod() |
||||
|
.AllowCredentials(); |
||||
|
}); |
||||
|
}); |
||||
|
builder.Host.AddAppSettingsSecretsJson() |
||||
|
.UseAutofac() |
||||
|
.UseSerilog((context, provider, config) => |
||||
|
{ |
||||
|
config.ReadFrom.Configuration(context.Configuration); |
||||
|
}); |
||||
|
|
||||
|
await builder.AddApplicationAsync<MicroServiceApplicationsSingleModule>(options => |
||||
|
{ |
||||
|
MicroServiceApplicationsSingleModule.ApplicationName = Environment.GetEnvironmentVariable("APPLICATION_NAME") |
||||
|
?? MicroServiceApplicationsSingleModule.ApplicationName; |
||||
|
options.ApplicationName = MicroServiceApplicationsSingleModule.ApplicationName; |
||||
|
options.Configuration.UserSecretsId = Environment.GetEnvironmentVariable("APPLICATION_USER_SECRETS_ID"); |
||||
|
options.Configuration.UserSecretsAssembly = typeof(MicroServiceApplicationsSingleModule).Assembly; |
||||
|
var pluginFolder = Path.Combine( |
||||
|
Directory.GetCurrentDirectory(), "Modules"); |
||||
|
DirectoryHelper.CreateIfNotExists(pluginFolder); |
||||
|
options.PlugInSources.AddFolder( |
||||
|
pluginFolder, |
||||
|
SearchOption.AllDirectories); |
||||
|
}); |
||||
|
|
||||
|
var app = builder.Build(); |
||||
|
|
||||
|
await app.InitializeApplicationAsync(); |
||||
|
|
||||
|
app.UseForwardedHeaders(); |
||||
|
if (app.Environment.IsDevelopment()) |
||||
|
{ |
||||
|
app.UseDeveloperExceptionPage(); |
||||
|
} |
||||
|
// app.UseAbpExceptionHandling();
|
||||
|
app.UseCookiePolicy(); |
||||
|
app.UseMapRequestLocalization(); |
||||
|
app.UseCorrelationId(); |
||||
|
app.UseStaticFiles(); |
||||
|
app.UseRouting(); |
||||
|
app.UseCors(); |
||||
|
app.UseAuthentication(); |
||||
|
app.UseMultiTenancy(); |
||||
|
app.UseUnitOfWork(); |
||||
|
app.UseAbpOpenIddictValidation(); |
||||
|
app.UseAbpSession(); |
||||
|
app.UseDynamicClaims(); |
||||
|
app.UseAuthorization(); |
||||
|
app.UseSwagger(); |
||||
|
app.UseSwaggerUI(options => |
||||
|
{ |
||||
|
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support App API"); |
||||
|
}); |
||||
|
app.UseAuditing(); |
||||
|
app.UseAbpSerilogEnrichers(); |
||||
|
app.UseConfiguredEndpoints(); |
||||
|
|
||||
|
await app.RunAsync(); |
||||
@ -0,0 +1,30 @@ |
|||||
|
{ |
||||
|
"iisSettings": { |
||||
|
"windowsAuthentication": false, |
||||
|
"anonymousAuthentication": true, |
||||
|
"iisExpress": { |
||||
|
"applicationUrl": "http://localhost:19139", |
||||
|
"sslPort": 0 |
||||
|
} |
||||
|
}, |
||||
|
"profiles": { |
||||
|
"LY.MicroService.Applications.Single": { |
||||
|
"commandName": "Project", |
||||
|
"dotnetRunMessages": true, |
||||
|
"launchBrowser": false, |
||||
|
"applicationUrl": "http://0.0.0.0:30001", |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Production" |
||||
|
} |
||||
|
}, |
||||
|
"LY.MicroService.Applications.Single.Development": { |
||||
|
"commandName": "Project", |
||||
|
"dotnetRunMessages": true, |
||||
|
"launchBrowser": false, |
||||
|
"applicationUrl": "http://0.0.0.0:30000", |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Development" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using Microsoft.Extensions.Options; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
using Swashbuckle.AspNetCore.SwaggerGen; |
||||
|
using Volo.Abp.AspNetCore.MultiTenancy; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single; |
||||
|
|
||||
|
public class TenantHeaderParamter : IOperationFilter |
||||
|
{ |
||||
|
private readonly AbpMultiTenancyOptions _multiTenancyOptions; |
||||
|
private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions; |
||||
|
public TenantHeaderParamter( |
||||
|
IOptions<AbpMultiTenancyOptions> multiTenancyOptions, |
||||
|
IOptions<AbpAspNetCoreMultiTenancyOptions> aspNetCoreMultiTenancyOptions) |
||||
|
{ |
||||
|
_multiTenancyOptions = multiTenancyOptions.Value; |
||||
|
_aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value; |
||||
|
} |
||||
|
|
||||
|
public void Apply(OpenApiOperation operation, OperationFilterContext context) |
||||
|
{ |
||||
|
if (_multiTenancyOptions.IsEnabled) |
||||
|
{ |
||||
|
operation.Parameters = operation.Parameters ?? new List<OpenApiParameter>(); |
||||
|
operation.Parameters.Add(new OpenApiParameter |
||||
|
{ |
||||
|
Name = _aspNetCoreMultiTenancyOptions.TenantKey, |
||||
|
In = ParameterLocation.Header, |
||||
|
Description = "Tenant Id in http header", |
||||
|
Required = false |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages.Handlers; |
||||
|
using LINGYUN.Abp.WeChat.Official.Messages.Models; |
||||
|
using LINGYUN.Abp.WeChat.Official.Services; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.WeChat.Official.Messages; |
||||
|
/// <summary>
|
||||
|
/// 文本消息客服回复
|
||||
|
/// </summary>
|
||||
|
public class TextMessageReplyContributor : IMessageHandleContributor<TextMessage> |
||||
|
{ |
||||
|
public async virtual Task HandleAsync(MessageHandleContext<TextMessage> context) |
||||
|
{ |
||||
|
var messageSender = context.ServiceProvider.GetRequiredService<IServiceCenterMessageSender>(); |
||||
|
|
||||
|
await messageSender.SendAsync( |
||||
|
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel( |
||||
|
context.Message.FromUserName, |
||||
|
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage( |
||||
|
context.Message.Content))); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages.Handlers; |
||||
|
using LINGYUN.Abp.WeChat.Official.Messages.Models; |
||||
|
using LINGYUN.Abp.WeChat.Official.Services; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.WeChat.Official.Messages; |
||||
|
/// <summary>
|
||||
|
/// 用户关注回复消息
|
||||
|
/// </summary>
|
||||
|
public class UserSubscribeEventContributor : IEventHandleContributor<UserSubscribeEvent> |
||||
|
{ |
||||
|
public async virtual Task HandleAsync(MessageHandleContext<UserSubscribeEvent> context) |
||||
|
{ |
||||
|
var messageSender = context.ServiceProvider.GetRequiredService<IServiceCenterMessageSender>(); |
||||
|
|
||||
|
await messageSender.SendAsync( |
||||
|
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessageModel( |
||||
|
context.Message.FromUserName, |
||||
|
new LINGYUN.Abp.WeChat.Official.Services.Models.TextMessage( |
||||
|
"感谢您的关注, 点击菜单了解更多."))); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages.Handlers; |
||||
|
using LINGYUN.Abp.WeChat.Work.Common.Messages.Models; |
||||
|
using LINGYUN.Abp.WeChat.Work.Messages; |
||||
|
|
||||
|
namespace LY.AIO.Applications.Single.WeChat.Work.Messages; |
||||
|
/// <summary>
|
||||
|
/// 文本消息客服回复
|
||||
|
/// </summary>
|
||||
|
public class TextMessageReplyContributor : IMessageHandleContributor<TextMessage> |
||||
|
{ |
||||
|
public async virtual Task HandleAsync(MessageHandleContext<TextMessage> context) |
||||
|
{ |
||||
|
var messageSender = context.ServiceProvider.GetRequiredService<IWeChatWorkMessageSender>(); |
||||
|
|
||||
|
await messageSender.SendAsync( |
||||
|
new LINGYUN.Abp.WeChat.Work.Messages.Models.WeChatWorkTextMessage( |
||||
|
context.Message.AgentId.ToString(), |
||||
|
new LINGYUN.Abp.WeChat.Work.Messages.Models.TextMessage( |
||||
|
context.Message.Content)) |
||||
|
{ |
||||
|
ToUser = context.Message.FromUserName, |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,249 @@ |
|||||
|
{ |
||||
|
"App": { |
||||
|
"ShowPii": true, |
||||
|
"SelfUrl": "http://127.0.0.1:30001/", |
||||
|
"CorsOrigins": "http://127.0.0.1:3100,http://127.0.0.1:30001", |
||||
|
"Urls": { |
||||
|
"Applications": { |
||||
|
"MVC": { |
||||
|
"RootUrl": "http://127.0.0.1:30001/", |
||||
|
"Urls": { |
||||
|
"Abp.Account.EmailConfirm": "Account/EmailConfirm", |
||||
|
"Abp.Account.EmailVerifyLogin": "Account/VerifyCode" |
||||
|
} |
||||
|
}, |
||||
|
"STS": { |
||||
|
"RootUrl": "http://127.0.0.1:30001/" |
||||
|
}, |
||||
|
"VueVbenAdmin": { |
||||
|
"RootUrl": "http://127.0.0.1:3100", |
||||
|
"Urls": { |
||||
|
"Abp.Account.EmailConfirm": "account/email-confirm" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"Auditing": { |
||||
|
"AllEntitiesSelector": true |
||||
|
}, |
||||
|
"DistributedCache": { |
||||
|
"HideErrors": true, |
||||
|
"KeyPrefix": "LINGYUN.Abp.Application", |
||||
|
"GlobalCacheEntryOptions": { |
||||
|
"SlidingExpiration": "30:00:00", |
||||
|
"AbsoluteExpirationRelativeToNow": "60:00:00" |
||||
|
} |
||||
|
}, |
||||
|
"ConnectionStrings": { |
||||
|
// "Default": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456;SslMode=None"//Mysql |
||||
|
"Default": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;"//Postgres |
||||
|
}, |
||||
|
"DistributedLock": { |
||||
|
"IsEnabled": true, |
||||
|
"Redis": { |
||||
|
"Configuration": "127.0.0.1,defaultDatabase=14" |
||||
|
} |
||||
|
}, |
||||
|
"Elsa": { |
||||
|
"Features": { |
||||
|
"DefaultPersistence": { |
||||
|
"Enabled": true, |
||||
|
"ConnectionStringIdentifier": "Default", |
||||
|
"EntityFrameworkCore": { |
||||
|
"MySql": { |
||||
|
"Enabled": true |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"Console": true, |
||||
|
"Http": true, |
||||
|
"Email": true, |
||||
|
"TemporalQuartz": true, |
||||
|
"JavaScriptActivities": true, |
||||
|
"UserTask": true, |
||||
|
"Conductor": true, |
||||
|
"Telnyx": true, |
||||
|
"BlobStoring": true, |
||||
|
"Emailing": true, |
||||
|
"Notification": true, |
||||
|
"Sms": true, |
||||
|
"IM": true, |
||||
|
"PublishWebhook": true, |
||||
|
"Webhooks": { |
||||
|
"Enabled": true, |
||||
|
"ConnectionStringIdentifier": "Default", |
||||
|
"EntityFrameworkCore": { |
||||
|
"MySql": { |
||||
|
"Enabled": true |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"WorkflowSettings": { |
||||
|
"Enabled": true, |
||||
|
"ConnectionStringIdentifier": "Default", |
||||
|
"EntityFrameworkCore": { |
||||
|
"MySql": { |
||||
|
"Enabled": true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"Server": { |
||||
|
"BaseUrl": "http://127.0.0.1:30000" |
||||
|
} |
||||
|
}, |
||||
|
"Quartz": { |
||||
|
"UsePersistentStore": false, |
||||
|
"Properties": { |
||||
|
"quartz.jobStore.dataSource": "tkm", |
||||
|
"quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz", |
||||
|
"quartz.dataSource.tkm.connectionStringName": "Default", |
||||
|
// "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz", |
||||
|
// "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform-V70;User Id=root;Password=123456", |
||||
|
// "quartz.dataSource.tkm.provider": "MySqlConnector", |
||||
|
"quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.PostgreSQLDelegate,Quartz", |
||||
|
"quartz.dataSource.tkm.connectionString": "Host=127.0.0.1;Database=Platform-V70;Username=postgres;Password=123456;", |
||||
|
"quartz.dataSource.tkm.provider": "Npgsql", |
||||
|
"quartz.jobStore.clustered": "true", |
||||
|
"quartz.serializer.type": "json" |
||||
|
} |
||||
|
}, |
||||
|
"Redis": { |
||||
|
"IsEnabled": true, |
||||
|
"Configuration": "127.0.0.1,defaultDatabase=15", |
||||
|
"InstanceName": "LINGYUN.Abp.Application" |
||||
|
}, |
||||
|
"Features": { |
||||
|
"Validation": { |
||||
|
"Redis": { |
||||
|
"Configuration": "127.0.0.1,defaultDatabase=13", |
||||
|
"InstanceName": "LINGYUN.Abp.Application" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"AuthServer": { |
||||
|
"UseOpenIddict": true, |
||||
|
"Authority": "http://127.0.0.1:30001/", |
||||
|
"Audience": "lingyun-abp-application", |
||||
|
"RequireHttpsMetadata": false, |
||||
|
"SwaggerClientId": "InternalServiceClient", |
||||
|
"SwaggerClientSecret": "1q2w3E*" |
||||
|
}, |
||||
|
"IdentityServer": { |
||||
|
"Clients": { |
||||
|
"VueAdmin": { |
||||
|
"ClientId": "vue-admin-client", |
||||
|
"RootUrl": "http://127.0.0.1:3100/" |
||||
|
}, |
||||
|
"InternalService": { |
||||
|
"ClientId": "InternalServiceClient" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"OpenIddict": { |
||||
|
"Applications": { |
||||
|
"VueAdmin": { |
||||
|
"ClientId": "vue-admin-client", |
||||
|
"RootUrl": "http://127.0.0.1:3100/" |
||||
|
}, |
||||
|
"InternalService": { |
||||
|
"ClientId": "InternalServiceClient" |
||||
|
} |
||||
|
}, |
||||
|
"Lifetime": { |
||||
|
"AuthorizationCode": "00:05:00", |
||||
|
"AccessToken": "14:00:00", |
||||
|
"DeviceCode": "00:10:00", |
||||
|
"IdentityToken": "00:20:00", |
||||
|
"RefreshToken": "14:00:00", |
||||
|
"RefreshTokenReuseLeeway": "00:00:30", |
||||
|
"UserCode": "00:10:00" |
||||
|
} |
||||
|
}, |
||||
|
"Identity": { |
||||
|
"Password": { |
||||
|
"RequiredLength": 6, |
||||
|
"RequiredUniqueChars": 0, |
||||
|
"RequireNonAlphanumeric": false, |
||||
|
"RequireLowercase": false, |
||||
|
"RequireUppercase": false, |
||||
|
"RequireDigit": false |
||||
|
}, |
||||
|
"Lockout": { |
||||
|
"AllowedForNewUsers": false, |
||||
|
"LockoutDuration": 5, |
||||
|
"MaxFailedAccessAttempts": 5 |
||||
|
}, |
||||
|
"SignIn": { |
||||
|
"RequireConfirmedEmail": false, |
||||
|
"RequireConfirmedPhoneNumber": false |
||||
|
} |
||||
|
}, |
||||
|
"FeatureManagement": { |
||||
|
"IsDynamicStoreEnabled": true |
||||
|
}, |
||||
|
"SettingManagement": { |
||||
|
"IsDynamicStoreEnabled": true |
||||
|
}, |
||||
|
"PermissionManagement": { |
||||
|
"IsDynamicStoreEnabled": true |
||||
|
}, |
||||
|
"TextTemplating": { |
||||
|
"IsDynamicStoreEnabled": true |
||||
|
}, |
||||
|
"WebhooksManagement": { |
||||
|
"IsDynamicStoreEnabled": true |
||||
|
}, |
||||
|
"Logging": { |
||||
|
"Serilog": { |
||||
|
"Elasticsearch": { |
||||
|
"IndexFormat": "abp.dev.logging-{0:yyyy.MM.dd}" |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"AuditLogging": { |
||||
|
"Elasticsearch": { |
||||
|
"IndexPrefix": "abp.dev.auditing" |
||||
|
} |
||||
|
}, |
||||
|
"Elasticsearch": { |
||||
|
"NodeUris": "http://127.0.0.1:9200" |
||||
|
}, |
||||
|
"Minio": { |
||||
|
"WithSSL": false, |
||||
|
"BucketName": "blobs", |
||||
|
"EndPoint": "127.0.0.1:19000", |
||||
|
"AccessKey": "ZD43kNpimiJf9mCuomTP", |
||||
|
"SecretKey": "w8IqMgi4Tnz0DGzN8jZ7IJWq7OEdbUnAU0jlZxQK", |
||||
|
"CreateBucketIfNotExists": false |
||||
|
}, |
||||
|
"Serilog": { |
||||
|
"MinimumLevel": { |
||||
|
"Default": "Information", |
||||
|
"Override": { |
||||
|
"System": "Warning", |
||||
|
"Microsoft": "Warning", |
||||
|
"DotNetCore": "Warning" |
||||
|
} |
||||
|
}, |
||||
|
"WriteTo": [ |
||||
|
{ |
||||
|
"Name": "Console", |
||||
|
"Args": { |
||||
|
"restrictedToMinimumLevel": "Debug", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"Name": "Elasticsearch", |
||||
|
"Args": { |
||||
|
"nodeUris": "http://127.0.0.1:9200", |
||||
|
"indexFormat": "abp.dev.logging-{0:yyyy.MM.dd}", |
||||
|
"autoRegisterTemplate": true, |
||||
|
"autoRegisterTemplateVersion": "ESv7" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,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" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,89 @@ |
|||||
|
{ |
||||
|
"Clock": { |
||||
|
"Kind": "Local" |
||||
|
}, |
||||
|
"Forwarded": { |
||||
|
"ForwardedHeaders": "XForwardedFor,XForwardedProto" |
||||
|
}, |
||||
|
"StringEncryption": { |
||||
|
"DefaultPassPhrase": "s46c5q55nxpeS8Ra", |
||||
|
"InitVectorBytes": "s83ng0abvd02js84", |
||||
|
"DefaultSalt": "sf&5)s3#" |
||||
|
}, |
||||
|
"Json": { |
||||
|
"OutputDateTimeFormat": "yyyy-MM-dd HH:mm:ss", |
||||
|
"InputDateTimeFormats": [ |
||||
|
"yyyy-MM-dd HH:mm:ss", |
||||
|
"yyyy-MM-ddTHH:mm:ss" |
||||
|
] |
||||
|
}, |
||||
|
"AllowedHosts": "*", |
||||
|
"Hosting": { |
||||
|
"BasePath": "" |
||||
|
}, |
||||
|
"Serilog": { |
||||
|
"MinimumLevel": { |
||||
|
"Default": "Information", |
||||
|
"Override": { |
||||
|
"System": "Warning", |
||||
|
"Microsoft": "Warning", |
||||
|
"DotNetCore": "Information" |
||||
|
} |
||||
|
}, |
||||
|
"Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], |
||||
|
"WriteTo": [ |
||||
|
{ |
||||
|
"Name": "Console", |
||||
|
"Args": { |
||||
|
"restrictedToMinimumLevel": "Debug", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"Name": "File", |
||||
|
"Args": { |
||||
|
"path": "Logs/Debug-.log", |
||||
|
"restrictedToMinimumLevel": "Debug", |
||||
|
"rollingInterval": "Day", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"Name": "File", |
||||
|
"Args": { |
||||
|
"path": "Logs/Info-.log", |
||||
|
"restrictedToMinimumLevel": "Information", |
||||
|
"rollingInterval": "Day", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"Name": "File", |
||||
|
"Args": { |
||||
|
"path": "Logs/Warn-.log", |
||||
|
"restrictedToMinimumLevel": "Warning", |
||||
|
"rollingInterval": "Day", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"Name": "File", |
||||
|
"Args": { |
||||
|
"path": "Logs/Error-.log", |
||||
|
"restrictedToMinimumLevel": "Error", |
||||
|
"rollingInterval": "Day", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"Name": "File", |
||||
|
"Args": { |
||||
|
"path": "Logs/Fatal-.log", |
||||
|
"restrictedToMinimumLevel": "Fatal", |
||||
|
"rollingInterval": "Day", |
||||
|
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
"use strict"; |
||||
|
|
||||
|
var gulp = require("gulp"), |
||||
|
path = require('path'), |
||||
|
copyResources = require('./node_modules/@abp/aspnetcore.mvc.ui/gulp/copy-resources.js'); |
||||
|
|
||||
|
exports.default = function(done){ |
||||
|
copyResources(path.resolve('./')); |
||||
|
done(); |
||||
|
}; |
||||
Loading…
Reference in new issue