diff --git a/.gitignore b/.gitignore
index 051ce9c8b..ca7fae3fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,11 @@ node_modules
vue.config.js
.env.production
task
+obj
+bin
+Logs
+appsettings.json
+appsettings.*.json
/tests/e2e/videos/
/tests/e2e/screenshots/
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj
new file mode 100644
index 000000000..aa212cfed
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN.Abp.Account.Application.Contracts.csproj
@@ -0,0 +1,26 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs
new file mode 100644
index 000000000..72a42a84f
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/AbpAccountApplicationContractsModule.cs
@@ -0,0 +1,27 @@
+using Volo.Abp.Account.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.Account
+{
+ [DependsOn(typeof(AbpAccountDomainSharedModule))]
+ public class AbpAccountApplicationContractsModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddBaseTypes(typeof(AccountResource))
+ .AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/RegisterDto.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/RegisterDto.cs
new file mode 100644
index 000000000..55a67a068
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/RegisterDto.cs
@@ -0,0 +1,13 @@
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Account
+{
+ public class RegisterDto
+ {
+ [Required]
+ [Phone]
+ [StringLength(IdentityUserConsts.MaxPhoneNumberLength)]
+ public string PhoneNumber { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/RegisterVerifyDto.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/RegisterVerifyDto.cs
new file mode 100644
index 000000000..dce404f29
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/RegisterVerifyDto.cs
@@ -0,0 +1,31 @@
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Auditing;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Account
+{
+ public class RegisterVerifyDto
+ {
+ [Required]
+ [Phone]
+ [StringLength(IdentityUserConsts.MaxPhoneNumberLength)]
+ public string PhoneNumber { get; set; }
+
+ [StringLength(IdentityUserConsts.MaxUserNameLength)]
+ public string UserName { get; set; }
+
+ [EmailAddress]
+ [StringLength(IdentityUserConsts.MaxEmailLength)]
+ public string EmailAddress { get; set; }
+
+ [Required]
+ [StringLength(IdentityUserConsts.MaxPasswordLength)]
+ [DataType(DataType.Password)]
+ [DisableAuditing]
+ public string Password { get; set; }
+
+ [Required]
+ [StringLength(6)]
+ public string VerifyCode { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/VerifyDto.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/VerifyDto.cs
new file mode 100644
index 000000000..03bcd2eda
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/VerifyDto.cs
@@ -0,0 +1,14 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace LINGYUN.Abp.Account
+{
+ public class VerifyDto
+ {
+ [Required]
+ [Phone]
+ public string PhoneNumber { get; set; }
+
+ [Required]
+ public PhoneNumberVerifyType VerifyType { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs
new file mode 100644
index 000000000..031b76359
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Account
+{
+ public interface IAccountAppService : IApplicationService
+ {
+ Task RegisterAsync(RegisterVerifyDto input);
+
+ Task VerifyPhoneNumberAsync(VerifyDto input);
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/en.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/en.json
new file mode 100644
index 000000000..b61468521
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/en.json
@@ -0,0 +1,8 @@
+{
+ "culture": "en",
+ "texts": {
+ "PhoneNumberNotRegisterd": "The registered mobile phone number is not registered!",
+ "PhoneVerifyCodeInvalid": "The phone verification code is invalid or expired!",
+ "PhoneVerifyCodeNotRepeatSend": "Phone verification code cannot be sent repeatedly within {0} minutes!"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json
new file mode 100644
index 000000000..f054a8048
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json
@@ -0,0 +1,8 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "PhoneNumberNotRegisterd": "手机号码未注册!",
+ "PhoneVerifyCodeInvalid": "手机验证码无效或已经过期!",
+ "PhoneVerifyCodeNotRepeatSend": "手机验证码不能在 {0} 分钟内重复发送!"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj
new file mode 100644
index 000000000..3ddea3d7a
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj
@@ -0,0 +1,18 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs
new file mode 100644
index 000000000..a0c4d6f9f
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs
@@ -0,0 +1,13 @@
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Account
+{
+ [DependsOn(
+ typeof(AbpAccountDomainModule),
+ typeof(Volo.Abp.Account.AbpAccountApplicationModule),
+ typeof(AbpAccountApplicationContractsModule))]
+ public class AbpAccountApplicationModule : AbpModule
+ {
+
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs
new file mode 100644
index 000000000..7a824cb11
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountAppService.cs
@@ -0,0 +1,187 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Caching.Distributed;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Caching;
+using Volo.Abp.Identity;
+using Volo.Abp.Settings;
+using Volo.Abp.Sms;
+
+namespace LINGYUN.Abp.Account
+{
+ ///
+ /// 用户注册服务
+ ///
+ public class AccountAppService : ApplicationService, IAccountAppService
+ {
+ protected ISmsSender SmsSender { get; }
+ protected IdentityUserManager UserManager { get; }
+ protected IIdentityUserRepository UserRepository { get; }
+ protected IDistributedCache Cache { get; }
+ protected PhoneNumberTokenProvider PhoneNumberTokenProvider { get; }
+ public AccountAppService(
+ ISmsSender smsSender,
+ IdentityUserManager userManager,
+ IIdentityUserRepository userRepository,
+ IDistributedCache cache,
+ PhoneNumberTokenProvider phoneNumberTokenProvider)
+ {
+ Cache = cache;
+ SmsSender = smsSender;
+ UserManager = userManager;
+ UserRepository = userRepository;
+ PhoneNumberTokenProvider = phoneNumberTokenProvider;
+ LocalizationResource = typeof(Localization.AccountResource);
+ }
+ ///
+ /// 用户注册
+ ///
+ ///
+ ///
+ ///
+ /// 用户通过VerifyPhoneNumber接口发送到手机的验证码,传递注册信息注册用户
+ /// 如果没有此手机号的缓存记录或验证码不匹配,抛出验证码无效的异常
+ /// 用户注册成功,清除缓存的验证码记录
+ ///
+ public virtual async Task RegisterAsync(RegisterVerifyDto input)
+ {
+ var phoneVerifyCacheKey = NormalizeCacheKey(input.PhoneNumber);
+
+ var phoneVerifyCacheItem = await Cache.GetAsync(phoneVerifyCacheKey);
+ if(phoneVerifyCacheItem == null || !phoneVerifyCacheItem.VerifyCode.Equals(input.VerifyCode))
+ {
+ throw new UserFriendlyException(L["PhoneVerifyCodeInvalid"]);
+ }
+
+ await CheckSelfRegistrationAsync();
+
+ var userEmail = input.EmailAddress ?? input.PhoneNumber + "@abp.io";
+ var userName = input.UserName ?? input.PhoneNumber;
+ var user = new IdentityUser(GuidGenerator.Create(), userName, userEmail, CurrentTenant.Id);
+
+ (await UserManager.CreateAsync(user, input.Password)).CheckErrors();
+
+ await UserManager.SetPhoneNumberAsync(user, input.PhoneNumber);
+ await UserManager.SetEmailAsync(user, userEmail);
+ await UserManager.AddDefaultRolesAsync(user);
+
+ await Cache.RemoveAsync(phoneVerifyCacheKey);
+
+ return ObjectMapper.Map(user);
+ }
+ ///
+ /// 验证手机号码
+ ///
+ ///
+ ///
+ ///
+ /// 用户传递手机号码及认证类型
+ /// 1、如果认证类型为注册:
+ /// 先查询是否存在此手机号的缓存验证码信息,如果存在,抛出不能重复发送验证码异常
+ /// 随机生成6位纯数字验证码,通过短信接口服务发送到用户手机,并缓存验证码,设定一个有效时长
+ ///
+ /// 2、如果认证类型为登录:
+ /// 先查询是否存在此手机号的缓存验证码信息,如果存在,抛出不能重复发送验证码异常
+ /// 通过手机号查询用户信息,如果用户不存在,抛出手机号未注册异常
+ /// 调用PhoneNumberTokenProvider接口生成6位手机验证码,用途为 phone_verify
+ /// 发送手机验证码到用户手机,并缓存验证码,设定一个有效时长
+ ///
+ /// 用户调用 IdentityServer4/connect/token 登录系统(需要引用LINGYUN.Abp.IdentityServer.SmsValidator模块)
+ /// 参数1:grant_type=phone_verify
+ /// 参数2:phone_number=手机号码
+ /// 参数3:phone_verify_code=手机验证码
+ /// 参数4:client_id=客户端标识
+ /// 参数5:client_secret=客户端密钥
+ ///
+ public virtual async Task VerifyPhoneNumberAsync(VerifyDto input)
+ {
+ var verifyCodeExpiration = await SettingProvider.GetAsync(AccountSettingNames.PhoneVerifyCodeExpiration);
+ var phoneVerifyCacheKey = NormalizeCacheKey(input.PhoneNumber);
+ var verifyCacheItem = await Cache.GetAsync(phoneVerifyCacheKey);
+ if (verifyCacheItem != null)
+ {
+ throw new UserFriendlyException(L["PhoneVerifyCodeNotRepeatSend", verifyCodeExpiration]);
+ }
+ verifyCacheItem = new AccountRegisterVerifyCacheItem
+ {
+ PhoneNumber = input.PhoneNumber,
+ };
+ if (input.VerifyType == PhoneNumberVerifyType.Register)
+ {
+ var phoneVerifyCode = new Random().Next(100000, 999999);
+ verifyCacheItem.VerifyCode = phoneVerifyCode.ToString();
+ var templateCode = await SettingProvider.GetOrNullAsync(AccountSettingNames.SmsRegisterTemplateCode);
+ await SendPhoneVerifyMessageAsync(templateCode, input.PhoneNumber, phoneVerifyCode.ToString());
+ }
+ else
+ {
+ var phoneVerifyCode = await SendSigninVerifyCodeAsync(input.PhoneNumber);
+ verifyCacheItem.VerifyCode = phoneVerifyCode;
+ }
+ var cacheOptions = new DistributedCacheEntryOptions
+ {
+ AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(verifyCodeExpiration)
+ };
+ await Cache.SetAsync(phoneVerifyCacheKey, verifyCacheItem, cacheOptions);
+ }
+
+ ///
+ /// 发送登录验证码
+ ///
+ /// 手机号
+ /// 返回登录验证码
+ protected virtual async Task SendSigninVerifyCodeAsync(string phoneNumber)
+ {
+ // 查找用户信息
+ var user = await UserRepository.FindByPhoneNumberAsync(phoneNumber);
+ if (user == null)
+ {
+ throw new UserFriendlyException(L["PhoneNumberNotRegisterd"]);
+ }
+ // 获取登录验证码模板号
+ var templateCode = await SettingProvider.GetOrNullAsync(AccountSettingNames.SmsSigninTemplateCode);
+ // 生成手机验证码
+ var phoneVerifyCode = await PhoneNumberTokenProvider.GenerateAsync("phone_verify", UserManager, user);
+ // 发送短信验证码
+ await SendPhoneVerifyMessageAsync(templateCode, user.PhoneNumber, phoneVerifyCode);
+
+ return phoneVerifyCode;
+ }
+ ///
+ /// 检查是否允许用户注册
+ ///
+ ///
+ protected virtual async Task CheckSelfRegistrationAsync()
+ {
+ if (!await SettingProvider.IsTrueAsync(Volo.Abp.Account.Settings.AccountSettingNames.IsSelfRegistrationEnabled))
+ {
+ throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
+ }
+ }
+ ///
+ /// 发送短信验证码
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected virtual async Task SendPhoneVerifyMessageAsync(string templateCode, string phoneNumber, string verifyCode)
+ {
+ var sendMessage = new SmsMessage(phoneNumber, "SendSmsMessage");
+ sendMessage.Properties.Add("code", verifyCode);
+ sendMessage.Properties.Add("TemplateCode", templateCode);
+ await SmsSender.SendAsync(sendMessage);
+ }
+ ///
+ /// 格式化缓存主键
+ ///
+ /// 手机号码
+ ///
+ protected string NormalizeCacheKey(string phoneNumber)
+ {
+ return $"ACCOUNT-PHONE:{phoneNumber}";
+ }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj
new file mode 100644
index 000000000..815f27437
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN.Abp.Account.Domain.Shared.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs
new file mode 100644
index 000000000..b30dde284
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AbpAccountDomainSharedModule.cs
@@ -0,0 +1,19 @@
+using LINGYUN.Abp.Account.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Account
+{
+ [DependsOn(typeof(AbpLocalizationModule))]
+ public class AbpAccountDomainSharedModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.Resources
+ .Add("zh-Hans");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountRegisterVerifyCacheItem.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountRegisterVerifyCacheItem.cs
new file mode 100644
index 000000000..faf78244a
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountRegisterVerifyCacheItem.cs
@@ -0,0 +1,8 @@
+namespace LINGYUN.Abp.Account
+{
+ public class AccountRegisterVerifyCacheItem
+ {
+ public string PhoneNumber { get; set; }
+ public string VerifyCode { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountSettingNames.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountSettingNames.cs
new file mode 100644
index 000000000..d3bf2abd9
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/AccountSettingNames.cs
@@ -0,0 +1,19 @@
+namespace LINGYUN.Abp.Account
+{
+ public class AccountSettingNames
+ {
+ public const string GroupName = "Abp.Account";
+ ///
+ /// 短信验证码过期时间
+ ///
+ public const string PhoneVerifyCodeExpiration = GroupName + ".PhoneVerifyCodeExpiration";
+ ///
+ /// 用户注册短信验证码模板号
+ ///
+ public const string SmsRegisterTemplateCode = GroupName + ".SmsRegisterTemplateCode";
+ ///
+ /// 用户登录短信验证码模板号
+ ///
+ public const string SmsSigninTemplateCode = GroupName + ".SmsSigninTemplateCode";
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/AccountResource.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/AccountResource.cs
new file mode 100644
index 000000000..c132a9b9b
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/Localization/AccountResource.cs
@@ -0,0 +1,9 @@
+using Volo.Abp.Localization;
+
+namespace LINGYUN.Abp.Account.Localization
+{
+ [LocalizationResourceName("LINYUNAbpAccount")]
+ public class AccountResource
+ {
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/PhoneNumberVerifyType.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/PhoneNumberVerifyType.cs
new file mode 100644
index 000000000..3fb05ebcd
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain.Shared/LINGYUN/Abp/Account/PhoneNumberVerifyType.cs
@@ -0,0 +1,8 @@
+namespace LINGYUN.Abp.Account
+{
+ public enum PhoneNumberVerifyType : sbyte
+ {
+ Register = 0,
+ Signin = 10
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN.Abp.Account.Domain.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN.Abp.Account.Domain.csproj
new file mode 100644
index 000000000..74d1df10d
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN.Abp.Account.Domain.csproj
@@ -0,0 +1,26 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs
new file mode 100644
index 000000000..0ad58c817
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs
@@ -0,0 +1,25 @@
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.Account
+{
+ [DependsOn(typeof(AbpAccountDomainSharedModule))]
+ public class AbpAccountDomainModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountSettingDefinitionProvider.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountSettingDefinitionProvider.cs
new file mode 100644
index 000000000..b8f347730
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountSettingDefinitionProvider.cs
@@ -0,0 +1,33 @@
+using LINGYUN.Abp.Account.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Settings;
+
+namespace LINGYUN.Abp.Account
+{
+ public class AbpAccountSettingDefinitionProvider : SettingDefinitionProvider
+ {
+ public override void Define(ISettingDefinitionContext context)
+ {
+
+ context.Add(GetAccountSettings());
+ }
+
+ protected SettingDefinition[] GetAccountSettings()
+ {
+ return new SettingDefinition[]
+ {
+ new SettingDefinition(AccountSettingNames.SmsRegisterTemplateCode,
+ "SMS_190728520", L("DisplayName:SmsRegisterTemplateCode"), L("Description:SmsRegisterTemplateCode")),
+ new SettingDefinition(AccountSettingNames.SmsSigninTemplateCode,
+ "SMS_190728516", L("DisplayName:SmsSigninTemplateCode"), L("Description:SmsSigninTemplateCode")),
+ new SettingDefinition(AccountSettingNames.PhoneVerifyCodeExpiration,
+ "3", L("DisplayName:PhoneVerifyCodeExpiration"), L("Description:PhoneVerifyCodeExpiration")),
+ };
+ }
+
+ protected LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/IIdentityUserRepository.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/IIdentityUserRepository.cs
new file mode 100644
index 000000000..54817fc92
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/IIdentityUserRepository.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Account
+{
+ public interface IIdentityUserRepository : IReadOnlyRepository
+ {
+ Task FindByPhoneNumberAsync(string phoneNumber);
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/Localization/Resources/en.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/Localization/Resources/en.json
new file mode 100644
index 000000000..b49a3d2b8
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/Localization/Resources/en.json
@@ -0,0 +1,11 @@
+{
+ "culture": "en",
+ "texts": {
+ "DisplayName:SmsRegisterTemplateCode": "Register sms template",
+ "Description:SmsRegisterTemplateCode": "When the user registers, he/she should send the template number of the SMS verification code and fill in the template number of the corresponding cloud platform registration",
+ "DisplayName:SmsSigninTemplateCode": "Signin sms template",
+ "Description:SmsSigninTemplateCode": "When the user logs in, he/she should send the template number of the SMS verification code and fill in the template number of the corresponding cloud platform registration",
+ "DisplayName:PhoneVerifyCodeExpiration": "SMS verification code validity",
+ "Description:PhoneVerifyCodeExpiration": "The valid time for the user to send SMS verification code, unit m, default 3m"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json
new file mode 100644
index 000000000..c7a2c1df6
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/Localization/Resources/zh-Hans.json
@@ -0,0 +1,11 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "DisplayName:SmsRegisterTemplateCode": "用户注册短信模板",
+ "Description:SmsRegisterTemplateCode": "用户注册时发送短信验证码的模板号,填写对应云平台注册的模板号",
+ "DisplayName:SmsSigninTemplateCode": "用户登录短信模板",
+ "Description:SmsSigninTemplateCode": "用户登录时发送短信验证码的模板号,填写对应云平台注册的模板号",
+ "DisplayName:PhoneVerifyCodeExpiration": "短信验证码有效期",
+ "Description:PhoneVerifyCodeExpiration": "用户发送短信验证码的有效时长,单位m,默认3m"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN.Abp.Account.HttpApi.csproj b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN.Abp.Account.HttpApi.csproj
new file mode 100644
index 000000000..b2242b858
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN.Abp.Account.HttpApi.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs
new file mode 100644
index 000000000..fb49e8866
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AbpAccountHttpApiModule.cs
@@ -0,0 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Account
+{
+ [DependsOn(
+ typeof(AbpAccountApplicationContractsModule),
+ typeof(AbpAspNetCoreMvcModule))]
+ public class AbpAccountHttpApiModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(mvcBuilder =>
+ {
+ mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountHttpApiModule).Assembly);
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs
new file mode 100644
index 000000000..f1cc98255
--- /dev/null
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/AccountController.cs
@@ -0,0 +1,36 @@
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Account;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Account
+{
+ [RemoteService(Name = AccountRemoteServiceConsts.RemoteServiceName)]
+ [Area("account")]
+ [Route("api/account/phone")]
+ public class AccountController : AbpController, IAccountAppService
+ {
+ protected IAccountAppService AccountAppService { get; }
+ public AccountController(
+ IAccountAppService accountAppService)
+ {
+ AccountAppService = accountAppService;
+ }
+
+ [HttpPost]
+ [Route("register")]
+ public virtual async Task RegisterAsync(RegisterVerifyDto input)
+ {
+ return await AccountAppService.RegisterAsync(input);
+ }
+
+ [HttpPost]
+ [Route("verify")]
+ public virtual async Task VerifyPhoneNumberAsync(VerifyDto input)
+ {
+ await AccountAppService.VerifyPhoneNumberAsync(input);
+ }
+ }
+}
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application.Contracts/LINGYUN.ApiGateway.Application.Contracts.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application.Contracts/LINGYUN.ApiGateway.Application.Contracts.csproj
index 6e2e554f6..a66598500 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application.Contracts/LINGYUN.ApiGateway.Application.Contracts.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application.Contracts/LINGYUN.ApiGateway.Application.Contracts.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application/LINGYUN.ApiGateway.Application.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application/LINGYUN.ApiGateway.Application.csproj
index 9251af785..e87e99db2 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application/LINGYUN.ApiGateway.Application.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application/LINGYUN.ApiGateway.Application.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain.Shared/LINGYUN.ApiGateway.Domain.Shared.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain.Shared/LINGYUN.ApiGateway.Domain.Shared.csproj
index 8a56afa78..f6eb8b1c0 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain.Shared/LINGYUN.ApiGateway.Domain.Shared.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain.Shared/LINGYUN.ApiGateway.Domain.Shared.csproj
@@ -16,7 +16,7 @@
-
+
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain/LINGYUN.ApiGateway.Domain.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain/LINGYUN.ApiGateway.Domain.csproj
index 1732dc330..72e481122 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain/LINGYUN.ApiGateway.Domain.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Domain/LINGYUN.ApiGateway.Domain.csproj
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.EntityFrameworkCore/LINGYUN.ApiGateway.EntityFrameworkCore.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.EntityFrameworkCore/LINGYUN.ApiGateway.EntityFrameworkCore.csproj
index 43738db7d..ab90b85d8 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.EntityFrameworkCore/LINGYUN.ApiGateway.EntityFrameworkCore.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.EntityFrameworkCore/LINGYUN.ApiGateway.EntityFrameworkCore.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi.Client/LINGYUN.ApiGateway.HttpApi.Client.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi.Client/LINGYUN.ApiGateway.HttpApi.Client.csproj
index b6916c730..9239a7892 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi.Client/LINGYUN.ApiGateway.HttpApi.Client.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi.Client/LINGYUN.ApiGateway.HttpApi.Client.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi/LINGYUN.ApiGateway.HttpApi.csproj b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi/LINGYUN.ApiGateway.HttpApi.csproj
index e5939dd48..a9dc687be 100644
--- a/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi/LINGYUN.ApiGateway.HttpApi.csproj
+++ b/aspnet-core/modules/apigateway/LINGYUN.ApiGateway.HttpApi/LINGYUN.ApiGateway.HttpApi.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/ConsumerServiceSelector.cs b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/ConsumerServiceSelector.cs
index 89f3b75a6..17a965873 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/ConsumerServiceSelector.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/ConsumerServiceSelector.cs
@@ -11,12 +11,21 @@ using Volo.Abp.EventBus.Distributed;
namespace DotNetCore.CAP
{
+ ///
+ /// 消费者查找器
+ ///
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)]
[ExposeServices(typeof(IConsumerServiceSelector), typeof(ConsumerServiceSelector))]
public class ConsumerServiceSelector : Internal.ConsumerServiceSelector
{
+ ///
+ /// Abp分布式事件配置
+ ///
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; }
+ ///
+ /// 服务提供者
+ ///
protected IServiceProvider ServiceProvider { get; }
///
@@ -27,7 +36,11 @@ namespace DotNetCore.CAP
ServiceProvider = serviceProvider;
AbpDistributedEventBusOptions = distributedEventBusOptions.Value;
}
-
+ ///
+ /// 查找消费者集合
+ ///
+ ///
+ ///
protected override IEnumerable FindConsumersFromInterfaceTypes(IServiceProvider provider)
{
var executorDescriptorList =
@@ -55,7 +68,12 @@ namespace DotNetCore.CAP
}
return executorDescriptorList;
}
-
+ ///
+ /// 获取事件处理器集合
+ ///
+ ///
+ ///
+ ///
protected virtual IEnumerable GetHandlerDescription(Type eventType, Type typeInfo)
{
var serviceTypeInfo = typeof(IDistributedEventHandler<>)
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.csproj b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.csproj
index ca43fecff..e55aa8625 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.csproj
+++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.csproj
@@ -3,11 +3,19 @@
netstandard2.0
+ true
+ false
+ 2.8.0
+
+
+
+ D:\LocalNuget
+ D:\Projects\MicroService\CRM\Vue\vue-abp\aspnet-core\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.xml
-
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml
new file mode 100644
index 000000000..3cb756744
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml
@@ -0,0 +1,158 @@
+
+
+
+ LINGYUN.Abp.EventBus.CAP
+
+
+
+
+ 消费者查找器
+
+
+
+
+ Abp分布式事件配置
+
+
+
+
+ 服务提供者
+
+
+
+
+ Creates a new .
+
+
+
+
+ 查找消费者集合
+
+
+
+
+
+
+ 获取事件处理器集合
+
+
+
+
+
+
+
+ AbpCAPEventBusModule
+
+
+
+
+ ConfigureServices
+
+
+
+
+
+ CAP分布式事件总线
+
+
+
+
+ Abp分布式事件总线配置
+
+
+
+
+ CAP消息发布接口
+
+
+
+
+ 本地事件处理器工厂对象集合
+
+
+
+
+ 本地事件集合
+
+
+
+
+ constructor
+
+
+
+
+
+
+
+ 订阅事件
+
+
+
+
+
+
+
+ 退订事件
+
+ 事件类型
+
+
+
+
+ 退订事件
+
+ 事件类型
+ 事件处理器
+
+
+
+ 退订事件
+
+ 事件类型
+ 事件处理器工厂
+
+
+
+ 退订所有事件
+
+ 事件类型
+
+
+
+ 订阅事件
+
+ 事件类型
+ 事件处理器
+
+
+
+
+ 发布事件
+
+ 事件类型
+ 事件数据对象
+
+
+
+
+ 获取事件处理器工厂列表
+
+
+
+
+
+
+ CAP ServiceCollectionExtensions
+
+
+
+
+ Adds and configures the consistence services for the consistency.
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/AbpCAPEventBusModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/AbpCAPEventBusModule.cs
index 9bb24ef87..3bf6ebb55 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/AbpCAPEventBusModule.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/AbpCAPEventBusModule.cs
@@ -5,9 +5,16 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Abp.EventBus.CAP
{
+ ///
+ /// AbpCAPEventBusModule
+ ///
[DependsOn(typeof(AbpEventBusModule))]
public class AbpCAPEventBusModule : AbpModule
{
+ ///
+ /// ConfigureServices
+ ///
+ ///
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CAPDistributedEventBus.cs b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CAPDistributedEventBus.cs
index 8dd564da1..e67f0bf8d 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CAPDistributedEventBus.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CAPDistributedEventBus.cs
@@ -14,17 +14,36 @@ using Volo.Abp.Threading;
namespace LINGYUN.Abp.EventBus.CAP
{
+ ///
+ /// CAP分布式事件总线
+ ///
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)]
[ExposeServices(typeof(IDistributedEventBus), typeof(CAPDistributedEventBus))]
public class CAPDistributedEventBus : EventBusBase, IDistributedEventBus
{
+ ///
+ /// Abp分布式事件总线配置
+ ///
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; }
+ ///
+ /// CAP消息发布接口
+ ///
protected readonly ICapPublisher CapPublisher;
- //TODO: Accessing to the List may not be thread-safe!
+ ///
+ /// 本地事件处理器工厂对象集合
+ ///
protected ConcurrentDictionary> HandlerFactories { get; }
+ ///
+ /// 本地事件集合
+ ///
protected ConcurrentDictionary EventTypes { get; }
-
+ ///
+ /// constructor
+ ///
+ ///
+ ///
+ ///
public CAPDistributedEventBus(IServiceScopeFactory serviceScopeFactory,
IOptions distributedEventBusOptions,
ICapPublisher capPublisher) : base(serviceScopeFactory)
@@ -34,13 +53,22 @@ namespace LINGYUN.Abp.EventBus.CAP
HandlerFactories = new ConcurrentDictionary>();
EventTypes = new ConcurrentDictionary();
}
-
+ ///
+ /// 订阅事件
+ ///
+ ///
+ ///
+ ///
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
{
//This is handled by CAP ConsumerServiceSelector
throw new NotImplementedException();
}
-
+ ///
+ /// 退订事件
+ ///
+ /// 事件类型
+ ///
public override void Unsubscribe(Func action)
{
Check.NotNull(action, nameof(action));
@@ -51,14 +79,12 @@ namespace LINGYUN.Abp.EventBus.CAP
factories.RemoveAll(
factory =>
{
- var singleInstanceFactory = factory as SingleInstanceHandlerFactory;
- if (singleInstanceFactory == null)
+ if (!(factory is SingleInstanceHandlerFactory singleInstanceFactory))
{
return false;
}
- var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler;
- if (actionHandler == null)
+ if (!(singleInstanceFactory.HandlerInstance is ActionEventHandler actionHandler))
{
return false;
}
@@ -67,7 +93,11 @@ namespace LINGYUN.Abp.EventBus.CAP
});
});
}
-
+ ///
+ /// 退订事件
+ ///
+ /// 事件类型
+ /// 事件处理器
public override void Unsubscribe(Type eventType, IEventHandler handler)
{
GetOrCreateHandlerFactories(eventType)
@@ -80,29 +110,50 @@ namespace LINGYUN.Abp.EventBus.CAP
);
});
}
-
+ ///
+ /// 退订事件
+ ///
+ /// 事件类型
+ /// 事件处理器工厂
public override void Unsubscribe(Type eventType, IEventHandlerFactory factory)
{
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory));
}
-
+ ///
+ /// 退订所有事件
+ ///
+ /// 事件类型
public override void UnsubscribeAll(Type eventType)
{
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear());
}
-
+ ///
+ /// 订阅事件
+ ///
+ /// 事件类型
+ /// 事件处理器
+ ///
public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class
{
return Subscribe(typeof(TEvent), handler);
}
-
+ ///
+ /// 发布事件
+ ///
+ /// 事件类型
+ /// 事件数据对象
+ ///
public override async Task PublishAsync(Type eventType, object eventData)
{
var eventName = EventNameAttribute.GetNameOrDefault(eventType);
await CapPublisher.PublishAsync(eventName, eventData);
}
-
+ ///
+ /// 获取事件处理器工厂列表
+ ///
+ ///
+ ///
protected override IEnumerable GetHandlerFactories(Type eventType)
{
var handlerFactoryList = new List();
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
index 0b77dce6f..d6a9afd09 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
@@ -3,8 +3,17 @@ using System;
namespace Microsoft.Extensions.DependencyInjection
{
+ ///
+ /// CAP ServiceCollectionExtensions
+ ///
public static class ServiceCollectionExtensions
{
+ ///
+ /// Adds and configures the consistence services for the consistency.
+ ///
+ ///
+ ///
+ ///
public static IServiceCollection AddCAPEventBus(this IServiceCollection services, Action capAction)
{
services.AddCap(capAction);
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj
new file mode 100644
index 000000000..64736c78d
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINGYUN.Abp.Sms.Aliyun.csproj
@@ -0,0 +1,25 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AbpAliyunSmsModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AbpAliyunSmsModule.cs
new file mode 100644
index 000000000..e36a96c42
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AbpAliyunSmsModule.cs
@@ -0,0 +1,35 @@
+using LINYUN.Abp.Sms.Aliyun.Localization;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Json;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.Sms;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINYUN.Abp.Sms.Aliyun
+{
+ [DependsOn(
+ typeof(AbpSmsModule),
+ typeof(AbpJsonModule),
+ typeof(AbpLocalizationModule))]
+ public class AbpAliyunSmsModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+ Configure(configuration.GetSection("Aliyun:Sms"));
+
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Add("en")
+ .AddVirtualJson("/LINYUN/Abp/Sms/Aliyun/Localization/Resources");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsOptions.cs
new file mode 100644
index 000000000..e4abc6eaa
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsOptions.cs
@@ -0,0 +1,46 @@
+namespace LINYUN.Abp.Sms.Aliyun
+{
+ public class AliyunSmsOptions
+ {
+ ///
+ /// 区域Id
+ ///
+ public string RegionId { get; set; } = "default";
+ ///
+ /// 阿里云sms服务域名
+ ///
+ public string Domain { get; set; } = "dysmsapi.aliyuncs.com";
+ ///
+ /// 调用方法名称
+ ///
+ public string ActionName { get; set; } = "SendSms";
+ ///
+ /// ApiKey
+ ///
+ public string AccessKeyId { get; set; }
+ ///
+ /// Api密钥
+ ///
+ public string AccessKeySecret { get; set; }
+ ///
+ /// 默认版本号
+ ///
+ public string DefaultVersion { get; set; } = "2017-05-25";
+ ///
+ /// 默认签名
+ ///
+ public string DefaultSignName { get; set; }
+ ///
+ /// 默认短信模板号
+ ///
+ public string DefaultTemplateCode { get; set; }
+ ///
+ /// 开发人员号码,当应用处于开发模式时,默认所有信息都会发送到此号码
+ ///
+ public string DeveloperPhoneNumber { get; set; } = "13800138000";
+ ///
+ /// 展示错误给客户端
+ ///
+ public bool VisableErrorToClient { get; set; } = false;
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsResponse.cs b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsResponse.cs
new file mode 100644
index 000000000..66e623ffa
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsResponse.cs
@@ -0,0 +1,76 @@
+using LINYUN.Abp.Sms.Aliyun.Localization;
+using System;
+using Volo.Abp;
+using Volo.Abp.Localization;
+
+namespace LINYUN.Abp.Sms.Aliyun
+{
+ public class AliyunSmsResponse
+ {
+ public string Code { get; set; }
+ public string Message { get; set; }
+ public string RequestId { get; set; }
+
+ public bool IsSuccess()
+ {
+ return "ok".Equals(Code, StringComparison.CurrentCultureIgnoreCase);
+ }
+
+ public ILocalizableString GetErrorMessage()
+ {
+ Check.NotNullOrWhiteSpace(Code, nameof(Code));
+ switch (Code)
+ {
+ case "isv.SMS_TEMPLATE_ILLEGAL":
+ return LocalizableString.Create("SMS_TEMPLATE_ILLEGAL");
+ case "isv.SMS_SIGNATURE_ILLEGAL":
+ return LocalizableString.Create("SMS_SIGNATURE_ILLEGAL");
+ case "isv.MOBILE_NUMBER_ILLEGAL":
+ return LocalizableString.Create("MOBILE_NUMBER_ILLEGAL");
+ case "isv.TEMPLATE_MISSING_PARAMETERS":
+ return LocalizableString.Create("TEMPLATE_MISSING_PARAMETERS");
+ case "isv.EXTEND_CODE_ERROR":
+ return LocalizableString.Create("EXTEND_CODE_ERROR");
+ case "isv.DOMESTIC_NUMBER_NOT_SUPPORTED":
+ return LocalizableString.Create("DOMESTIC_NUMBER_NOT_SUPPORTED");
+ case "isv.DAY_LIMIT_CONTROL":
+ return LocalizableString.Create("DAY_LIMIT_CONTROL");
+ case "isv.SMS_CONTENT_ILLEGAL":
+ return LocalizableString.Create("SMS_CONTENT_ILLEGAL");
+ case "isv.SMS_SIGN_ILLEGAL":
+ return LocalizableString.Create("SMS_SIGN_ILLEGAL");
+ case "isp.RAM_PERMISSION_DENY":
+ return LocalizableString.Create("RAM_PERMISSION_DENY");
+ case "isp.OUT_OF_SERVICE":
+ return LocalizableString.Create("OUT_OF_SERVICE");
+ case "isv.PRODUCT_UN_SUBSCRIPT":
+ return LocalizableString.Create("PRODUCT_UN_SUBSCRIPT");
+ case "isv.PRODUCT_UNSUBSCRIBE":
+ return LocalizableString.Create("PRODUCT_UNSUBSCRIBE");
+ case "isv.ACCOUNT_NOT_EXISTS":
+ return LocalizableString.Create("ACCOUNT_NOT_EXISTS");
+ case "isv.ACCOUNT_ABNORMAL":
+ return LocalizableString.Create("ACCOUNT_ABNORMAL");
+ case "isv.INVALID_PARAMETERS":
+ return LocalizableString.Create("INVALID_PARAMETERS");
+ case "isv.SYSTEM_ERROR":
+ return LocalizableString.Create("SYSTEM_ERROR");
+ case "isv.INVALID_JSON_PARAM":
+ return LocalizableString.Create("INVALID_JSON_PARAM");
+ case "isv.BLACK_KEY_CONTROL_LIMIT":
+ return LocalizableString.Create("BLACK_KEY_CONTROL_LIMIT");
+ case "isv.PARAM_LENGTH_LIMIT":
+ return LocalizableString.Create("PARAM_LENGTH_LIMIT");
+ case "isv.PARAM_NOT_SUPPORT_URL":
+ return LocalizableString.Create("PARAM_NOT_SUPPORT_URL");
+ case "isv.AMOUNT_NOT_ENOUGH":
+ return LocalizableString.Create("AMOUNT_NOT_ENOUGH");
+ case "isv.TEMPLATE_PARAMS_ILLEGAL":
+ return LocalizableString.Create("TEMPLATE_PARAMS_ILLEGAL");
+ default:
+ throw new AbpException("no error code define!");
+
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs
new file mode 100644
index 000000000..d17888502
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsSender.cs
@@ -0,0 +1,115 @@
+using Aliyun.Acs.Core;
+using Aliyun.Acs.Core.Exceptions;
+using Aliyun.Acs.Core.Http;
+using Aliyun.Acs.Core.Profile;
+using LINYUN.Abp.Sms.Aliyun.Localization;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Options;
+using System;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Json;
+using Volo.Abp.Localization;
+using Volo.Abp.Sms;
+
+namespace LINYUN.Abp.Sms.Aliyun
+{
+ [Dependency(ServiceLifetime.Singleton)]
+ [ExposeServices(typeof(ISmsSender), typeof(AliyunSmsSender))]
+ public class AliyunSmsSender : ISmsSender
+ {
+ protected AliyunSmsOptions Options { get; }
+ protected IJsonSerializer JsonSerializer { get; }
+ protected IHostEnvironment Environment { get; }
+ protected IServiceProvider ServiceProvider { get; }
+ public AliyunSmsSender(
+ IHostEnvironment environment,
+ IJsonSerializer jsonSerializer,
+ IServiceProvider serviceProvider,
+ IOptions options)
+ {
+ Options = options.Value;
+ Environment = environment;
+ JsonSerializer = jsonSerializer;
+ ServiceProvider = serviceProvider;
+ }
+
+ public Task SendAsync(SmsMessage smsMessage)
+ {
+ CommonRequest request = new CommonRequest
+ {
+ Method = MethodType.POST,
+ Domain = Options.Domain,
+ Action = Options.ActionName,
+ Version = Options.DefaultVersion
+ };
+ if (smsMessage.Properties.TryGetValue("TemplateCode", out object template))
+ {
+ request.AddQueryParameters("TemplateCode", template.ToString());
+ smsMessage.Properties.Remove("TemplateCode");
+ }
+ else
+ {
+ Check.NotNullOrWhiteSpace(Options.DefaultTemplateCode, nameof(Options.DefaultTemplateCode));
+ request.AddQueryParameters("TemplateCode", Options.DefaultTemplateCode);
+ }
+
+ if (smsMessage.Properties.TryGetValue("SignName", out object signName))
+ {
+ request.AddQueryParameters("SignName", signName.ToString());
+ smsMessage.Properties.Remove("SignName");
+ }
+ else
+ {
+ Check.NotNullOrWhiteSpace(Options.DefaultSignName, nameof(Options.DefaultSignName));
+ request.AddQueryParameters("SignName", Options.DefaultSignName);
+ }
+ if (Environment.IsDevelopment())
+ {
+ Check.NotNullOrWhiteSpace(Options.DeveloperPhoneNumber, nameof(Options.DeveloperPhoneNumber));
+ request.AddQueryParameters("PhoneNumbers", Options.DeveloperPhoneNumber);
+ }
+ else
+ {
+ request.AddQueryParameters("PhoneNumbers", smsMessage.PhoneNumber);
+ }
+
+ var queryParamJson = JsonSerializer.Serialize(smsMessage.Properties);
+ request.AddQueryParameters("TemplateParam", queryParamJson);
+ try
+ {
+ IClientProfile profile = DefaultProfile.GetProfile(Options.RegionId, Options.AccessKeyId, Options.AccessKeySecret);
+ IAcsClient client = new DefaultAcsClient(profile);
+ CommonResponse response = client.GetCommonResponse(request);
+ var responseContent = Encoding.Default.GetString(response.HttpResponse.Content);
+ var aliyunResponse = JsonSerializer.Deserialize(responseContent);
+ if (!aliyunResponse.IsSuccess())
+ {
+ var localizerFactory = ServiceProvider.GetRequiredService();
+ var localizerError = aliyunResponse.GetErrorMessage().Localize(localizerFactory);
+ if (Options.VisableErrorToClient)
+ {
+ var localizer = ServiceProvider.GetRequiredService>();
+ localizerError = localizer["SendMessageFailed", localizerError];
+ throw new UserFriendlyException(localizerError);
+ }
+ throw new AbpException($"Text message sending failed:{localizerError}!");
+ }
+ }
+ catch(ServerException se)
+ {
+ throw new AbpException("Sending text messages to aliyun server is abnormal", se);
+ }
+ catch(ClientException ce)
+ {
+ throw new AbpException("A client exception occurred in sending SMS messages", ce);
+ }
+
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsSuccessResponse.cs b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsSuccessResponse.cs
new file mode 100644
index 000000000..4d0ad74c7
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/AliyunSmsSuccessResponse.cs
@@ -0,0 +1,7 @@
+namespace LINYUN.Abp.Sms.Aliyun
+{
+ public class AliyunSmsSuccessResponse : AliyunSmsResponse
+ {
+ public string BizId { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/AliyunSmsResource.cs b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/AliyunSmsResource.cs
new file mode 100644
index 000000000..b1220263e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/AliyunSmsResource.cs
@@ -0,0 +1,9 @@
+using Volo.Abp.Localization;
+
+namespace LINYUN.Abp.Sms.Aliyun.Localization
+{
+ [LocalizationResourceName("AliyunSms")]
+ public class AliyunSmsResource
+ {
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/Resources/en.json b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/Resources/en.json
new file mode 100644
index 000000000..2f947f883
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/Resources/en.json
@@ -0,0 +1,29 @@
+{
+ "culture": "en",
+ "texts": {
+ "SendMessageFailed": "Text message sending failed:{0}",
+ "SMS_TEMPLATE_ILLEGAL": "template is not valid (not present or blocked)",
+ "SMS_SIGNATURE_ILLEGAL": "the signature is not valid (not present or blocked)",
+ "MOBILE_NUMBER_ILLEGAL": "invalid phone number ",
+ "TEMPLATE_MISSING_PARAMETERS": "template variable missing corresponding parameter value ",
+ "EXTEND_CODE_ERROR": "Error using extension code",
+ "DOMESTIC_NUMBER_NOT_SUPPORTED": "the template for international/Hong Kong, Macao and Taiwan messages does not support the sending of domestic Numbers",
+ "DAY_LIMIT_CONTROL": "trigger daily send limit ",
+ "SMS_CONTENT_ILLEGAL": "SMS content contains prohibited content ",
+ "SMS_SIGN_ILLEGAL": "signature is not allowed ",
+ "RAM_PERMISSION_DENY": "RAM permission DENY",
+ "OUT_OF_SERVICE": "business down ",
+ "PRODUCT_UN_SUBSCRIPT": "ali cloud customers who have not opened cloud communication products",
+ "PRODUCT_UNSUBSCRIBE": "product not opened ",
+ "ACCOUNT_NOT_EXISTS": "the account does not exist ",
+ "ACCOUNT_ABNORMAL": "account abnormal ",
+ "INVALID_PARAMETERS": "parameter exception ",
+ "SYSTEM_ERROR": "system error ",
+ "INVALID_JSON_PARAM": "invalid JSON parameter, only accept string value ",
+ "BLACK_KEY_CONTROL_LIMIT": "blacklist control ",
+ "PARAM_LENGTH_LIMIT": "the parameter exceeds the length limit ",
+ "PARAM_NOT_SUPPORT_URL": "unsupported URL",
+ "AMOUNT_NOT_ENOUGH": "insufficient account balance ",
+ "TEMPLATE_PARAMS_ILLEGAL": "template variable contains illegal keyword"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/Resources/zh-Hans.json b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/Resources/zh-Hans.json
new file mode 100644
index 000000000..a56cd5852
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Sms.Aliyun/LINYUN/Abp/Sms/Aliyun/Localization/Resources/zh-Hans.json
@@ -0,0 +1,29 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "SendMessageFailed": "发送短信错误:{0}",
+ "SMS_TEMPLATE_ILLEGAL": "模板不合法(不存在或被拉黑)",
+ "SMS_SIGNATURE_ILLEGAL": "签名不合法(不存在或被拉黑)",
+ "MOBILE_NUMBER_ILLEGAL": "无效的电话号码",
+ "TEMPLATE_MISSING_PARAMETERS": "模板变量缺少对应参数值",
+ "EXTEND_CODE_ERROR": "扩展码使用错误",
+ "DOMESTIC_NUMBER_NOT_SUPPORTED": "国际/港澳台消息模板不支持发送境内号码",
+ "DAY_LIMIT_CONTROL": "触发日发送限额",
+ "SMS_CONTENT_ILLEGAL": "短信内容包含禁止发送内容",
+ "SMS_SIGN_ILLEGAL": "签名禁止使用",
+ "RAM_PERMISSION_DENY": "没有访问权限",
+ "OUT_OF_SERVICE": "业务停机",
+ "PRODUCT_UN_SUBSCRIPT": "未开通云通信产品的阿里云客户",
+ "PRODUCT_UNSUBSCRIBE": "产品未开通",
+ "ACCOUNT_NOT_EXISTS": "账户不存在",
+ "ACCOUNT_ABNORMAL": "账户异常",
+ "INVALID_PARAMETERS": "参数异常",
+ "SYSTEM_ERROR": "系统错误",
+ "INVALID_JSON_PARAM": "JSON参数不合法,只接受字符串值",
+ "BLACK_KEY_CONTROL_LIMIT": "黑名单管控",
+ "PARAM_LENGTH_LIMIT": "参数超出长度限制",
+ "PARAM_NOT_SUPPORT_URL": "不支持URL",
+ "AMOUNT_NOT_ENOUGH": "账户余额不足",
+ "TEMPLATE_PARAMS_ILLEGAL": "模版变量里包含非法关键字"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/common/LINGYUN.Common.EventBus/LINGYUN.Common.EventBus.csproj b/aspnet-core/modules/common/LINGYUN.Common.EventBus/LINGYUN.Common.EventBus.csproj
index fb24e3e53..7b0206dd6 100644
--- a/aspnet-core/modules/common/LINGYUN.Common.EventBus/LINGYUN.Common.EventBus.csproj
+++ b/aspnet-core/modules/common/LINGYUN.Common.EventBus/LINGYUN.Common.EventBus.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN.Abp.IdentityServer.Application.Contracts.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN.Abp.IdentityServer.Application.Contracts.csproj
index 936e1ad68..0e784b770 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN.Abp.IdentityServer.Application.Contracts.csproj
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application.Contracts/LINGYUN.Abp.IdentityServer.Application.Contracts.csproj
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN.Abp.IdentityServer.Application.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN.Abp.IdentityServer.Application.csproj
index 21e931179..86577be15 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN.Abp.IdentityServer.Application.csproj
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN.Abp.IdentityServer.Application.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs
index 2b35871ed..21c238f41 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/ApiResources/ApiResourceAppService.cs
@@ -46,10 +46,12 @@ namespace LINGYUN.Abp.IdentityServer.ApiResources
{
throw new UserFriendlyException(L[AbpIdentityServerErrorConsts.ApiResourceNameExisted, apiResourceCreate.Name]);
}
- var apiResource = new ApiResource(GuidGenerator.Create(), apiResourceCreate.Name,
- apiResourceCreate.DisplayName, apiResourceCreate.Description);
- apiResource.Enabled = apiResourceCreate.Enabled;
- foreach(var userClaim in apiResourceCreate.UserClaims)
+ var apiResource = new ApiResource(GuidGenerator.Create(), apiResourceCreate.Name,
+ apiResourceCreate.DisplayName, apiResourceCreate.Description)
+ {
+ Enabled = apiResourceCreate.Enabled
+ };
+ foreach (var userClaim in apiResourceCreate.UserClaims)
{
apiResource.AddUserClaim(userClaim.Type);
}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs
index 01af8f7e4..8dd96466d 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.Application/LINGYUN/Abp/IdentityServer/Clients/ClientAppService.cs
@@ -87,10 +87,12 @@ namespace LINGYUN.Abp.IdentityServer.Clients
{
throw new UserFriendlyException(L[AbpIdentityServerErrorConsts.ClientIdExisted, clientCreate.ClientId]);
}
- var client = new Client(GuidGenerator.Create(), clientCreate.ClientId);
- client.ClientName = clientCreate.ClientName;
- client.Description = clientCreate.Description;
- foreach(var grantType in clientCreate.AllowedGrantTypes)
+ var client = new Client(GuidGenerator.Create(), clientCreate.ClientId)
+ {
+ ClientName = clientCreate.ClientName,
+ Description = clientCreate.Description
+ };
+ foreach (var grantType in clientCreate.AllowedGrantTypes)
{
client.AddGrantType(grantType.GrantType);
}
@@ -295,46 +297,48 @@ namespace LINGYUN.Abp.IdentityServer.Clients
}
var srcClient = await ClientRepository.GetAsync(clientCloneInput.SourceClientId);
- var client = new Client(GuidGenerator.Create(), clientCloneInput.ClientId);
- client.ClientName = clientCloneInput.ClientName;
- client.Description = clientCloneInput.Description;
- client.AbsoluteRefreshTokenLifetime = srcClient.AbsoluteRefreshTokenLifetime;
- client.AccessTokenLifetime = srcClient.AccessTokenLifetime;
- client.AccessTokenType = srcClient.AccessTokenType;
- client.AllowAccessTokensViaBrowser = srcClient.AllowAccessTokensViaBrowser;
- client.AllowOfflineAccess = srcClient.AllowOfflineAccess;
- client.AllowPlainTextPkce = srcClient.AllowPlainTextPkce;
- client.AllowRememberConsent = srcClient.AllowRememberConsent;
- client.AlwaysIncludeUserClaimsInIdToken = srcClient.AlwaysIncludeUserClaimsInIdToken;
- client.AlwaysSendClientClaims = srcClient.AlwaysSendClientClaims;
- client.AuthorizationCodeLifetime = srcClient.AuthorizationCodeLifetime;
- client.BackChannelLogoutSessionRequired = srcClient.BackChannelLogoutSessionRequired;
-
- client.BackChannelLogoutUri = srcClient.BackChannelLogoutUri;
- client.ClientClaimsPrefix = srcClient.ClientClaimsPrefix;
- client.ConsentLifetime = srcClient.ConsentLifetime;
- client.DeviceCodeLifetime = srcClient.DeviceCodeLifetime;
- client.Enabled = srcClient.Enabled;
- client.EnableLocalLogin = srcClient.EnableLocalLogin;
- client.FrontChannelLogoutSessionRequired = srcClient.FrontChannelLogoutSessionRequired;
- client.FrontChannelLogoutUri = srcClient.FrontChannelLogoutUri;
-
- client.IdentityTokenLifetime = srcClient.IdentityTokenLifetime;
- client.IncludeJwtId = srcClient.IncludeJwtId;
- client.LogoUri = srcClient.LogoUri;
- client.PairWiseSubjectSalt = srcClient.PairWiseSubjectSalt;
- client.ProtocolType = srcClient.ProtocolType;
- client.RefreshTokenExpiration = srcClient.RefreshTokenExpiration;
- client.RefreshTokenUsage = srcClient.RefreshTokenUsage;
- client.RequireClientSecret = srcClient.RequireClientSecret;
- client.RequireConsent = srcClient.RequireConsent;
-
- client.RequirePkce = srcClient.RequirePkce;
- client.SlidingRefreshTokenLifetime = srcClient.SlidingRefreshTokenLifetime;
- client.UpdateAccessTokenClaimsOnRefresh = srcClient.UpdateAccessTokenClaimsOnRefresh;
-
- client.UserCodeType = srcClient.UserCodeType;
- client.UserSsoLifetime = srcClient.UserSsoLifetime;
+ var client = new Client(GuidGenerator.Create(), clientCloneInput.ClientId)
+ {
+ ClientName = clientCloneInput.ClientName,
+ Description = clientCloneInput.Description,
+ AbsoluteRefreshTokenLifetime = srcClient.AbsoluteRefreshTokenLifetime,
+ AccessTokenLifetime = srcClient.AccessTokenLifetime,
+ AccessTokenType = srcClient.AccessTokenType,
+ AllowAccessTokensViaBrowser = srcClient.AllowAccessTokensViaBrowser,
+ AllowOfflineAccess = srcClient.AllowOfflineAccess,
+ AllowPlainTextPkce = srcClient.AllowPlainTextPkce,
+ AllowRememberConsent = srcClient.AllowRememberConsent,
+ AlwaysIncludeUserClaimsInIdToken = srcClient.AlwaysIncludeUserClaimsInIdToken,
+ AlwaysSendClientClaims = srcClient.AlwaysSendClientClaims,
+ AuthorizationCodeLifetime = srcClient.AuthorizationCodeLifetime,
+ BackChannelLogoutSessionRequired = srcClient.BackChannelLogoutSessionRequired,
+
+ BackChannelLogoutUri = srcClient.BackChannelLogoutUri,
+ ClientClaimsPrefix = srcClient.ClientClaimsPrefix,
+ ConsentLifetime = srcClient.ConsentLifetime,
+ DeviceCodeLifetime = srcClient.DeviceCodeLifetime,
+ Enabled = srcClient.Enabled,
+ EnableLocalLogin = srcClient.EnableLocalLogin,
+ FrontChannelLogoutSessionRequired = srcClient.FrontChannelLogoutSessionRequired,
+ FrontChannelLogoutUri = srcClient.FrontChannelLogoutUri,
+
+ IdentityTokenLifetime = srcClient.IdentityTokenLifetime,
+ IncludeJwtId = srcClient.IncludeJwtId,
+ LogoUri = srcClient.LogoUri,
+ PairWiseSubjectSalt = srcClient.PairWiseSubjectSalt,
+ ProtocolType = srcClient.ProtocolType,
+ RefreshTokenExpiration = srcClient.RefreshTokenExpiration,
+ RefreshTokenUsage = srcClient.RefreshTokenUsage,
+ RequireClientSecret = srcClient.RequireClientSecret,
+ RequireConsent = srcClient.RequireConsent,
+
+ RequirePkce = srcClient.RequirePkce,
+ SlidingRefreshTokenLifetime = srcClient.SlidingRefreshTokenLifetime,
+ UpdateAccessTokenClaimsOnRefresh = srcClient.UpdateAccessTokenClaimsOnRefresh,
+
+ UserCodeType = srcClient.UserCodeType,
+ UserSsoLifetime = srcClient.UserSsoLifetime
+ };
if (clientCloneInput.CopyAllowedCorsOrigin)
{
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN.Abp.IdentityServer.HttpApi.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN.Abp.IdentityServer.HttpApi.csproj
index b9615fd30..9c4eafc5c 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN.Abp.IdentityServer.HttpApi.csproj
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.HttpApi/LINGYUN.Abp.IdentityServer.HttpApi.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN.Abp.IdentityServer.SmsValidator.csproj b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN.Abp.IdentityServer.SmsValidator.csproj
new file mode 100644
index 000000000..e79d7fe1b
--- /dev/null
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN.Abp.IdentityServer.SmsValidator.csproj
@@ -0,0 +1,26 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmValidatorModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmValidatorModule.cs
new file mode 100644
index 000000000..1a1bb6fe4
--- /dev/null
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmValidatorModule.cs
@@ -0,0 +1,37 @@
+using LINGYUN.Abp.IdentityServer.SmsValidator;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.IdentityServer;
+using Volo.Abp.IdentityServer.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.IdentityServer
+{
+ [DependsOn(typeof(AbpIdentityServerDomainModule))]
+ public class AbpIdentityServerSmValidatorModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddExtensionGrantValidator();
+ });
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/Resources");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json
new file mode 100644
index 000000000..dd09cb2a5
--- /dev/null
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json
@@ -0,0 +1,9 @@
+{
+ "culture": "en",
+ "texts": {
+ "InvalidGrant:GrantTypeInvalid": "Type of authorization not allowed!",
+ "InvalidGrant:PhoneVerifyInvalid": "phone verification code failed!",
+ "InvalidGrant:PhoneOrTokenCodeNotFound": "Phone number or verify code not found!",
+ "InvalidGrant:PhoneNumberNotRegister": "The registered mobile phone number is not registered!"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json
new file mode 100644
index 000000000..c75aaff38
--- /dev/null
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json
@@ -0,0 +1,9 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "InvalidGrant:GrantTypeInvalid": "不被允许的授权类型!",
+ "InvalidGrant:PhoneVerifyInvalid": "手机验证码无效或已过期!",
+ "InvalidGrant:PhoneOrTokenCodeNotFound": "手机号码或手机验证码未输入!",
+ "InvalidGrant:PhoneNumberNotRegister": "登录的手机号码未注册!"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/SmsValidator/SmsTokenGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/SmsValidator/SmsTokenGrantValidator.cs
new file mode 100644
index 000000000..95ddd848d
--- /dev/null
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/SmsValidator/SmsTokenGrantValidator.cs
@@ -0,0 +1,100 @@
+using IdentityModel;
+using IdentityServer4.Events;
+using IdentityServer4.Models;
+using IdentityServer4.Services;
+using IdentityServer4.Validation;
+using LINGYUN.Abp.Account;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Volo.Abp.IdentityServer.Localization;
+using Volo.Abp.Security.Claims;
+using IdentityUser = Volo.Abp.Identity.IdentityUser;
+
+namespace LINGYUN.Abp.IdentityServer.SmsValidator
+{
+ public class SmsTokenGrantValidator : IExtensionGrantValidator
+ {
+ protected ILogger Logger { get; }
+ protected IEventService EventService { get; }
+ protected IIdentityUserRepository UserRepository { get; }
+ protected UserManager UserManager { get; }
+ protected SignInManager SignInManager { get; }
+ protected IStringLocalizer Localizer { get; }
+ protected PhoneNumberTokenProvider PhoneNumberTokenProvider { get; }
+
+
+ public SmsTokenGrantValidator(
+ IEventService eventService,
+ UserManager userManager,
+ SignInManager signInManager,
+ IIdentityUserRepository userRepository,
+ IStringLocalizer stringLocalizer,
+ PhoneNumberTokenProvider phoneNumberTokenProvider,
+ ILogger logger)
+ {
+ Logger = logger;
+ EventService = eventService;
+ UserManager = userManager;
+ SignInManager = signInManager;
+ Localizer = stringLocalizer;
+ UserRepository = userRepository;
+ PhoneNumberTokenProvider = phoneNumberTokenProvider;
+ }
+
+ public string GrantType => SmsValidatorConsts.SmsValidatorGrantTypeName;
+
+ public async Task ValidateAsync(ExtensionGrantValidationContext context)
+ {
+ var raw = context.Request.Raw;
+ var credential = raw.Get(OidcConstants.TokenRequest.GrantType);
+ if (credential == null || !credential.Equals(GrantType))
+ {
+ Logger.LogWarning("Invalid grant type: not allowed");
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:GrantTypeInvalid"]);
+ return;
+ }
+ var phoneNumber = raw.Get(SmsValidatorConsts.SmsValidatorParamName);
+ var phoneToken = raw.Get(SmsValidatorConsts.SmsValidatorTokenName);
+ if (phoneNumber.IsNullOrWhiteSpace() || phoneToken.IsNullOrWhiteSpace())
+ {
+ Logger.LogWarning("Invalid grant type: phone number or token code not found");
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:PhoneOrTokenCodeNotFound"]);
+ return;
+ }
+ var currentUser = await UserRepository.FindByPhoneNumberAsync(phoneNumber);
+ if(currentUser == null)
+ {
+ Logger.LogWarning("Invalid grant type: phone number not register");
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:PhoneNumberNotRegister"]);
+ return;
+ }
+ var validResult = await PhoneNumberTokenProvider.ValidateAsync(SmsValidatorConsts.SmsValidatorPurpose, phoneToken, UserManager, currentUser);
+ if (!validResult)
+ {
+ Logger.LogWarning("Authentication failed for token: {0}, reason: invalid token", phoneToken);
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:PhoneVerifyInvalid"]);
+ await EventService.RaiseAsync(new UserLoginFailureEvent(currentUser.UserName, $"invalid phone verify code {phoneToken}", false));
+ return;
+ }
+ var sub = await UserManager.GetUserIdAsync(currentUser);
+
+ var additionalClaims = new List();
+ if (currentUser.TenantId.HasValue)
+ {
+ additionalClaims.Add(new Claim(AbpClaimTypes.TenantId, currentUser.TenantId?.ToString()));
+ }
+
+ await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, phoneNumber, null));
+ context.Result = new GrantValidationResult(sub, OidcConstants.AuthenticationMethods.ConfirmationBySms, additionalClaims.ToArray());
+ }
+ }
+}
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/SmsValidator/SmsValidatorConsts.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/SmsValidator/SmsValidatorConsts.cs
new file mode 100644
index 000000000..91ff74fb0
--- /dev/null
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/SmsValidator/SmsValidatorConsts.cs
@@ -0,0 +1,13 @@
+namespace LINGYUN.Abp.IdentityServer.SmsValidator
+{
+ public class SmsValidatorConsts
+ {
+ public const string SmsValidatorGrantTypeName = "phone_verify";
+
+ public const string SmsValidatorParamName = "phone_number";
+
+ public const string SmsValidatorTokenName = "phone_verify_code";
+
+ public const string SmsValidatorPurpose = "phone_verify";
+ }
+}
diff --git a/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application.Contracts/LINGYUN.Abp.PermissionManagement.Application.Contracts.csproj b/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application.Contracts/LINGYUN.Abp.PermissionManagement.Application.Contracts.csproj
index 7b26376aa..e904bdfa4 100644
--- a/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application.Contracts/LINGYUN.Abp.PermissionManagement.Application.Contracts.csproj
+++ b/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application.Contracts/LINGYUN.Abp.PermissionManagement.Application.Contracts.csproj
@@ -6,8 +6,8 @@
-
-
+
+
diff --git a/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN.Abp.PermissionManagement.Application.csproj b/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN.Abp.PermissionManagement.Application.csproj
index ad598bac1..1485e2519 100644
--- a/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN.Abp.PermissionManagement.Application.csproj
+++ b/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN.Abp.PermissionManagement.Application.csproj
@@ -6,8 +6,8 @@
-
-
+
+
diff --git a/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/PermissionAppService.cs b/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/PermissionAppService.cs
index 0561c1b08..c100c9030 100644
--- a/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/PermissionAppService.cs
+++ b/aspnet-core/modules/permissions/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/PermissionAppService.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
@@ -21,13 +22,16 @@ namespace LINGYUN.Abp.PermissionManagement
public class PermissionAppService : ApplicationService, IPermissionAppService
{
protected PermissionManagementOptions Options { get; }
+ protected IDistributedCache Cache { get; }
protected IPermissionGrantRepository PermissionGrantRepository { get; }
protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
public PermissionAppService(
+ IDistributedCache cache,
IPermissionGrantRepository permissionGrantRepository,
IPermissionDefinitionManager permissionDefinitionManager,
IOptions options)
{
+ Cache = cache;
Options = options.Value;
PermissionGrantRepository = permissionGrantRepository;
PermissionDefinitionManager = permissionDefinitionManager;
@@ -140,6 +144,10 @@ namespace LINGYUN.Abp.PermissionManagement
await PermissionGrantRepository.DeleteAsync(editPermission.Id);
}
}
+ // 同步变更缓存里的权限配置
+ var cacheKey = CalculateCacheKey(permission.Name, providerName, providerKey);
+ var cacheItem = new PermissionGrantCacheItem(permission.Name, permission.IsGranted);
+ await Cache.SetAsync(cacheKey, cacheItem);
}
}
@@ -153,5 +161,10 @@ namespace LINGYUN.Abp.PermissionManagement
await AuthorizationService.CheckAsync(policyName);
}
+
+ protected virtual string CalculateCacheKey(string name, string providerName, string providerKey)
+ {
+ return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey);
+ }
}
}
diff --git a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN.Abp.SettingManagement.Application.Contracts.csproj b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN.Abp.SettingManagement.Application.Contracts.csproj
index eed9ff929..15a6eb018 100644
--- a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN.Abp.SettingManagement.Application.Contracts.csproj
+++ b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN.Abp.SettingManagement.Application.Contracts.csproj
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN.Abp.SettingManagement.Application.csproj b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN.Abp.SettingManagement.Application.csproj
index 9611d9e3b..a4667a898 100644
--- a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN.Abp.SettingManagement.Application.csproj
+++ b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN.Abp.SettingManagement.Application.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.HttpApi/LINGYUN.Abp.SettingManagement.HttpApi.csproj b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.HttpApi/LINGYUN.Abp.SettingManagement.HttpApi.csproj
index 2064be3f3..5dba8495c 100644
--- a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.HttpApi/LINGYUN.Abp.SettingManagement.HttpApi.csproj
+++ b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.HttpApi/LINGYUN.Abp.SettingManagement.HttpApi.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application.Contracts/LINGYUN.Abp.TenantManagement.Application.Contracts.csproj b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application.Contracts/LINGYUN.Abp.TenantManagement.Application.Contracts.csproj
index b631f522e..77e7ab38d 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application.Contracts/LINGYUN.Abp.TenantManagement.Application.Contracts.csproj
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application.Contracts/LINGYUN.Abp.TenantManagement.Application.Contracts.csproj
@@ -6,8 +6,8 @@
-
-
+
+
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN.Abp.TenantManagement.Application.csproj b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN.Abp.TenantManagement.Application.csproj
index 0ab5dc32a..447d25c85 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN.Abp.TenantManagement.Application.csproj
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN.Abp.TenantManagement.Application.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.HttpApi/LINGYUN.Abp.TenantManagement.HttpApi.csproj b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.HttpApi/LINGYUN.Abp.TenantManagement.HttpApi.csproj
index 30322f5c6..2a0839fe6 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.HttpApi/LINGYUN.Abp.TenantManagement.HttpApi.csproj
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.HttpApi/LINGYUN.Abp.TenantManagement.HttpApi.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
index b70f9ad10..e370d890d 100644
--- a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
+++ b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
@@ -1,5 +1,6 @@
using DotNetCore.CAP;
using LINGYUN.Abp.EventBus.CAP;
+using LINGYUN.Abp.IdentityServer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
@@ -27,6 +28,7 @@ using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using Volo.Abp.Threading;
+
namespace AuthServer.Host
{
[DependsOn(
@@ -34,6 +36,7 @@ namespace AuthServer.Host
typeof(AbpAutofacModule),
typeof(AbpCAPEventBusModule),
typeof(AbpIdentityAspNetCoreModule),
+ typeof(AbpIdentityServerSmValidatorModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpIdentityServerEntityFrameworkCoreModule),
@@ -149,12 +152,8 @@ namespace AuthServer.Host
{
AsyncHelper.RunSync(async () =>
{
- using (var scope = context.ServiceProvider.CreateScope())
- {
- await scope.ServiceProvider
- .GetRequiredService()
- .SeedAsync();
- }
+ using var scope = context.ServiceProvider.CreateScope();
+ await scope.ServiceProvider.GetRequiredService().SeedAsync();
});
}
}
diff --git a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
index 0d343a9f4..a938bac49 100644
--- a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
+++ b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
@@ -20,20 +20,21 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/services/account/AuthServer.Host/EntityFrameworkCore/Identity/EfCoreIdentityUserExtensionRepository.cs b/aspnet-core/services/account/AuthServer.Host/EntityFrameworkCore/Identity/EfCoreIdentityUserExtensionRepository.cs
new file mode 100644
index 000000000..62593211a
--- /dev/null
+++ b/aspnet-core/services/account/AuthServer.Host/EntityFrameworkCore/Identity/EfCoreIdentityUserExtensionRepository.cs
@@ -0,0 +1,38 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.Identity;
+using Volo.Abp.Identity.EntityFrameworkCore;
+
+namespace AuthServer.Host.EntityFrameworkCore.Identity
+{
+ public class EfCoreIdentityUserRepository : EfCoreRepository, LINGYUN.Abp.Account.IIdentityUserRepository,
+ ITransientDependency
+ {
+ public EfCoreIdentityUserRepository(
+ IDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+ }
+
+ public async Task FindByPhoneNumberAsync(string phoneNumber)
+ {
+ return await WithDetails()
+ .Where(usr => usr.PhoneNumber.Equals(phoneNumber))
+ .FirstOrDefaultAsync();
+ }
+
+ public override IQueryable WithDetails()
+ {
+ return DbSet
+ .Include(x => x.Claims)
+ .Include(x => x.Roles)
+ .Include(x => x.Logins)
+ .Include(x => x.Tokens);
+ }
+ }
+}
diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj
index c2e62ed48..9578d5f3b 100644
--- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj
+++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/LINGYUN.ApiGateway.Host.csproj
@@ -17,10 +17,10 @@
-
-
-
-
+
+
+
+
diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
index 65062cd60..a0ab01d18 100644
--- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
+++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
@@ -28,11 +28,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EntityFrameworkCore/Identity/EfCoreIdentityUserExtensionRepository.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EntityFrameworkCore/Identity/EfCoreIdentityUserExtensionRepository.cs
new file mode 100644
index 000000000..7809d6795
--- /dev/null
+++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EntityFrameworkCore/Identity/EfCoreIdentityUserExtensionRepository.cs
@@ -0,0 +1,27 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.Identity;
+using Volo.Abp.Identity.EntityFrameworkCore;
+
+namespace LINGYUN.Platform.EntityFrameworkCore.Identity
+{
+ public class EfCoreIdentityUserRepository : EfCoreRepository, Abp.Account.IIdentityUserRepository,
+ ITransientDependency
+ {
+ public EfCoreIdentityUserRepository(
+ IDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+ }
+
+ public async Task FindByPhoneNumberAsync(string phoneNumber)
+ {
+ return await DbSet.Where(usr => usr.PhoneNumber.Equals(phoneNumber)).FirstOrDefaultAsync();
+ }
+ }
+}
diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EventBus/Handlers/TenantDeleteEventHandler.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EventBus/Handlers/TenantDeleteEventHandler.cs
index 7eb8fafd1..aae3df09a 100644
--- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EventBus/Handlers/TenantDeleteEventHandler.cs
+++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/EventBus/Handlers/TenantDeleteEventHandler.cs
@@ -33,33 +33,31 @@ namespace LINGYUN.Platform.EventBus.Handlers
public async Task HandleEventAsync(DeleteEventData eventData)
{
- using (var unitOfWork = UnitOfWorkManager.Begin())
+ using var unitOfWork = UnitOfWorkManager.Begin();
+ // 订阅租户删除事件,删除管理员角色所有权限
+ // TODO: 租户貌似不存在了,删除应该会失败
+ using (CurrentTenant.Change(eventData.Id))
{
- // 订阅租户删除事件,删除管理员角色所有权限
- // TODO: 租户貌似不存在了,删除应该会失败
- using (CurrentTenant.Change(eventData.Id))
- {
- // var grantPermissions = await PermissionGrantRepository.GetListAsync("R", "admin");
+ // var grantPermissions = await PermissionGrantRepository.GetListAsync("R", "admin");
- // EfCore MySql 批量删除还是一条一条的语句?
- // PermissionGrantRepository.GetDbSet().RemoveRange(grantPermissions);
- var permissionEntityType = PermissionGrantRepository.GetDbContext().Model.FindEntityType(typeof(PermissionGrant));
- var permissionTableName = permissionEntityType.GetTableName();
- var batchRmovePermissionSql = string.Empty;
- if (PermissionGrantRepository.GetDbContext().Database.IsMySql())
- {
- batchRmovePermissionSql = BuildMySqlBatchDeleteScript(permissionTableName, eventData.Id);
- }
- else
- {
- batchRmovePermissionSql = BuildSqlServerBatchDeleteScript(permissionTableName, eventData.Id);
- }
+ // EfCore MySql 批量删除还是一条一条的语句?
+ // PermissionGrantRepository.GetDbSet().RemoveRange(grantPermissions);
+ var permissionEntityType = PermissionGrantRepository.GetDbContext().Model.FindEntityType(typeof(PermissionGrant));
+ var permissionTableName = permissionEntityType.GetTableName();
+ var batchRmovePermissionSql = string.Empty;
+ if (PermissionGrantRepository.GetDbContext().Database.IsMySql())
+ {
+ batchRmovePermissionSql = BuildMySqlBatchDeleteScript(permissionTableName, eventData.Id);
+ }
+ else
+ {
+ batchRmovePermissionSql = BuildSqlServerBatchDeleteScript(permissionTableName, eventData.Id);
+ }
- await PermissionGrantRepository.GetDbContext().Database
- .ExecuteSqlRawAsync(batchRmovePermissionSql);
+ await PermissionGrantRepository.GetDbContext().Database
+ .ExecuteSqlRawAsync(batchRmovePermissionSql);
- await unitOfWork.CompleteAsync();
- }
+ await unitOfWork.CompleteAsync();
}
}
diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
index c0aa074f3..61d1a2047 100644
--- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
+++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
@@ -22,29 +22,33 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -52,8 +56,4 @@
-
-
-
-
diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs
index 04a4bade1..02fa0c688 100644
--- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs
+++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs
@@ -6,9 +6,11 @@ using LINGYUN.Abp.SettingManagement;
using LINGYUN.Abp.TenantManagement;
using LINGYUN.ApiGateway;
using LINGYUN.Platform.MultiTenancy;
+using LINYUN.Abp.Sms.Aliyun;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -47,6 +49,8 @@ namespace LINGYUN.Platform
typeof(ApiGatewayApplicationContractsModule),
typeof(AbpIdentityHttpApiModule),
typeof(AbpIdentityApplicationModule),
+ typeof(Abp.Account.AbpAccountApplicationModule),
+ typeof(Abp.Account.AbpAccountHttpApiModule),
typeof(AbpAccountApplicationModule),
typeof(AbpAccountHttpApiModule),
typeof(AbpIdentityServerApplicationModule),
@@ -65,6 +69,7 @@ namespace LINGYUN.Platform
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpCAPEventBusModule),
+ typeof(AbpAliyunSmsModule),
typeof(AbpAutofacModule)
)]
public class PlatformHttpApiHostModule : AbpModule
@@ -82,6 +87,11 @@ namespace LINGYUN.Platform
configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions);
});
});
+
+ PreConfigure(builder =>
+ {
+ builder.AddDefaultTokenProviders();
+ });
}
public override void ConfigureServices(ServiceConfigurationContext context)
@@ -176,7 +186,7 @@ namespace LINGYUN.Platform
// 审计日志
app.UseAuditing();
// 路由
- app.UseMvcWithDefaultRouteAndArea();
+ app.UseConfiguredEndpoints();
}
}
}
diff --git a/vueJs/src/api/users.ts b/vueJs/src/api/users.ts
index f31625227..5c6442986 100644
--- a/vueJs/src/api/users.ts
+++ b/vueJs/src/api/users.ts
@@ -263,7 +263,7 @@ export class UserUpdateDto implements IUserData {
/** 用户账户 */
userName!: string;
/** 用户简称 */
- surname!: string;
+ surname?: string;
/** 邮件地址 */
email!: string;
/** 联系方式 */
@@ -319,7 +319,7 @@ export interface IUserData {
/** 用户账户 */
userName: string
/** 用户简称 */
- surname: string
+ surname?: string
/** 邮件地址 */
email: string
/** 联系方式 */
diff --git a/vueJs/src/views/admin/users/components/UserCreateForm.vue b/vueJs/src/views/admin/users/components/UserCreateForm.vue
new file mode 100644
index 000000000..6196fe1ec
--- /dev/null
+++ b/vueJs/src/views/admin/users/components/UserCreateForm.vue
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('table.cancel') }}
+
+
+ {{ $t('table.confirm') }}
+
+
+
+
+
+
+
+
diff --git a/vueJs/src/views/admin/users/components/UserProfile.vue b/vueJs/src/views/admin/users/components/UserEditForm.vue
similarity index 82%
rename from vueJs/src/views/admin/users/components/UserProfile.vue
rename to vueJs/src/views/admin/users/components/UserEditForm.vue
index 0f2ae3e39..23454383c 100644
--- a/vueJs/src/views/admin/users/components/UserProfile.vue
+++ b/vueJs/src/views/admin/users/components/UserEditForm.vue
@@ -1,6 +1,6 @@
-
-
-
{{ $t('table.confirm') }}
@@ -134,8 +122,7 @@
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import UserApiService, {
UserDataDto,
- UserUpdateDto,
- UserCreateDto
+ UserUpdateDto
} from '@/api/users'
import RoleService from '@/api/roles'
import PermissionService, { PermissionDto, UpdatePermissionsDto } from '@/api/permission'
@@ -157,10 +144,9 @@ export default class extends Vue {
private roleList: {key: string, label: string, disabled: boolean}[]
/** 用户组 */
private userRoles: string[]
- private userPassword: string
private hasEditUser: boolean
private userRolesChanged: boolean
- private userProfile: UserDataDto
+ private userProfile: any
/** 是否加载用户权限 */
private hasLoadPermission: boolean
/** 用户权限数据 */
@@ -175,7 +161,6 @@ export default class extends Vue {
constructor() {
super()
this.activedTabPane = 'basic'
- this.userPassword = ''
this.hasEditUser = false
this.userRolesChanged = false
this.hasLoadPermission = false
@@ -274,8 +259,6 @@ export default class extends Vue {
this.userRoles = userRoleDto.items.map(r => r.name)
// 监听用户组变化
this.$watch('userRoles', this.onUserRolesChanged)
- // const data = await getSettings('U', UserModule.id)
- // console.log(data)
}
private async handleGetUserPermissions(id: string) {
@@ -290,20 +273,14 @@ export default class extends Vue {
this.editUserPermissions = permissions
}
- private onSubmit(formName: string) {
- const userProfileForm = this.$refs[formName] as any
- userProfileForm.validate(async(valid: boolean) => {
+ private onSubmit() {
+ const frmEditUser = this.$refs.formEditUser as any
+ frmEditUser.validate(async(valid: boolean) => {
if (valid) {
- if (!this.hasEditUser) {
- const createUserInput = this.createAddUserDto()
- this.userProfile = await UserApiService.createUser(createUserInput)
- this.$message.success(this.$t('users.createUserSuccess', { name: this.userProfile.name }).toString())
- } else {
- const updateUserInput = this.createEditUserDto()
- const user = await UserApiService.updateUser(this.userProfile.id, updateUserInput)
- this.userProfile = user
- this.$message.success(this.$t('users.updateUserSuccess', { name: this.userProfile.name }).toString())
- }
+ const updateUserInput = this.createEditUserDto()
+ const user = await UserApiService.updateUser(this.userProfile.id, updateUserInput)
+ this.userProfile = user
+ this.$message.success(this.l('users.updateUserSuccess', { name: this.userProfile.name }))
if (this.userRolesChanged) {
await UserApiService.setUserRoles(this.userProfile.id, this.userRoles)
}
@@ -312,7 +289,7 @@ export default class extends Vue {
setUserPermissions.permissions = this.editUserPermissions
await PermissionService.setPermissionsByKey('U', this.userProfile.id, setUserPermissions)
}
- userProfileForm.resetFields()
+ frmEditUser.resetFields()
this.$emit('onUserProfileChanged', this.userProfile.id)
this.onCancel()
} else {
@@ -329,8 +306,8 @@ export default class extends Vue {
private resetForm() {
this.activedTabPane = 'basic'
this.userRoles = new Array()
- const userProfileForm = this.$refs.profile as any
- userProfileForm.resetFields()
+ const frmEditUser = this.$refs.formEditUser as any
+ frmEditUser.resetFields()
if (this.hasLoadPermission) {
const userPermission = this.$refs.permissionTree as PermissionTree
userPermission.resetPermissions()
@@ -338,20 +315,6 @@ export default class extends Vue {
}
}
- private createAddUserDto() {
- const createUserInput = new UserCreateDto()
- createUserInput.name = this.userProfile.name
- createUserInput.userName = this.userProfile.userName
- createUserInput.password = this.userPassword
- createUserInput.surname = this.userProfile.surname
- createUserInput.email = this.userProfile.email
- createUserInput.phoneNumber = this.userProfile.phoneNumber
- createUserInput.twoFactorEnabled = this.userProfile.twoFactorEnabled
- createUserInput.lockoutEnabled = this.userProfile.lockoutEnabled
- createUserInput.roleNames = this.userRoles
- return createUserInput
- }
-
private createEditUserDto() {
const updateUserInput = new UserUpdateDto()
updateUserInput.name = this.userProfile.name
diff --git a/vueJs/src/views/admin/users/index.vue b/vueJs/src/views/admin/users/index.vue
index 59ace5415..9db64407c 100644
--- a/vueJs/src/views/admin/users/index.vue
+++ b/vueJs/src/views/admin/users/index.vue
@@ -115,7 +115,7 @@
:disabled="!checkPermission(['AbpIdentity.Users.Update'])"
size="mini"
type="primary"
- @click="handleShowUserProfile(row)"
+ @click="handleShowEditUserForm(row)"
>
{{ $t('users.updateUser') }}
@@ -159,13 +159,25 @@
/>
-
+
+
+
+
@@ -178,14 +190,16 @@ import { Component, Vue } from 'vue-property-decorator'
import Pagination from '@/components/Pagination/index.vue'
import { dateFormat } from '@/utils'
import UserApiService, { UserDataDto, UsersGetPagedDto } from '@/api/users'
-import UserProfile from './components/UserProfile.vue'
+import UserCreateForm from './components/UserCreateForm.vue'
+import UserEditForm from './components/UserEditForm.vue'
import { checkPermission } from '@/utils/permission'
@Component({
name: 'UserList',
components: {
Pagination,
- UserProfile
+ UserEditForm,
+ UserCreateForm
},
filters: {
dateTimeFilter(datetime: string) {
@@ -205,26 +219,26 @@ export default class extends Vue {
/** 最大用户数量 */
private totalCount: number
/** 当前编辑用户 */
- private editUserId: string
- /** 是否显示用户详情页 */
- private showUserProfile: boolean
- /** 用户详情页标题 */
- private userProfileTitle: any
+ private editUser: UserDataDto
/** 排序组别 */
private sortRule: { prop: string, sort: string }
/** 查询用户过滤参数 */
private getUserQuery: UsersGetPagedDto
+ private showCreateUserDialog: boolean
+ private showEditUserDialog: boolean
+
constructor() {
super()
this.totalCount = 0
- this.editUserId = ''
- this.showUserProfile = false
+ this.editUser = new UserDataDto()
this.userListLoading = false
- this.userProfileTitle = ''
this.sortRule = { prop: '', sort: '' }
this.getUserQuery = new UsersGetPagedDto()
this.userList = new Array()
+
+ this.showEditUserDialog = false
+ this.showCreateUserDialog = false
}
mounted() {
@@ -248,31 +262,24 @@ export default class extends Vue {
console.log('handleLockUser' + row.id)
}
- /** 展现用户详情页
- * @param row 操作行数据,可以转换为 UserDataDto 对象
- */
- private handleShowUserProfile(row: any) {
- this.editUserId = row.id
- this.userProfileTitle = this.$t('users.updateUser', { namec: row.name })
- this.showUserProfile = true
+ private handleShowEditUserForm(row: UserDataDto) {
+ this.editUser = row
+ this.showEditUserDialog = true
}
- /** 响应用户详情页关闭事件 */
private handleCloseUserProfile() {
- this.editUserId = ''
- this.showUserProfile = false
+ this.editUser = new UserDataDto()
+ this.showCreateUserDialog = false
+ this.showEditUserDialog = false
}
- /** 响应用户详情页变更事件 */
private handleUserProfileChanged() {
this.handleGetUsers()
}
- /** 新增用户事件,打开用户详情页 */
private handleCreateUser() {
- this.editUserId = ''
- this.userProfileTitle = this.$t('users.createUser')
- this.showUserProfile = true
+ this.editUser = new UserDataDto()
+ this.showCreateUserDialog = true
}
/** 响应更多操作命令 */
diff --git a/vueJs/start-vue-admin.bat b/vueJs/start-vue-admin.bat
new file mode 100644
index 000000000..07d606d74
--- /dev/null
+++ b/vueJs/start-vue-admin.bat
@@ -0,0 +1,14 @@
+@echo off
+cls
+chcp 65001
+
+echo. 启动后台管理UI
+
+if '%1' equ '--run' goto run
+if '%1' equ '' goto run
+exit
+
+:run
+npm run serve-nomock
+pause
+exit