diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/Microsoft/AspNetCore/Identity/PhoneNumberUserValidator.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/Microsoft/AspNetCore/Identity/PhoneNumberUserValidator.cs
index 861de3343..31a2237b4 100644
--- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/Microsoft/AspNetCore/Identity/PhoneNumberUserValidator.cs
+++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/Microsoft/AspNetCore/Identity/PhoneNumberUserValidator.cs
@@ -35,7 +35,9 @@ namespace Microsoft.AspNetCore.Identity
var phoneNumber = await manager.GetPhoneNumberAsync(user);
if (phoneNumber.IsNullOrWhiteSpace())
{
- throw new UserFriendlyException(_stringLocalizer["InvalidPhoneNumber"].Value, "InvalidPhoneNumber");
+ return;
+ // 如果用户没有手机号,不验证
+ //throw new UserFriendlyException(_stringLocalizer["InvalidPhoneNumber"].Value, "InvalidPhoneNumber");
}
var phoneNumberHasRegisted = await _identityUserRepository.PhoneNumberHasRegistedAsync(phoneNumber);
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/Class1.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/Class1.cs
deleted file mode 100644
index ea63efae8..000000000
--- a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/Class1.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace LINGYUN.Abp.IdentityServer.WeChatValidator
-{
- public class Class1
- {
- }
-}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
index c15204a42..307851aa6 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN.Abp.IdentityServer.WeChatValidator.csproj
@@ -5,6 +5,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs
new file mode 100644
index 000000000..97a959382
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerWeChatValidatorModule.cs
@@ -0,0 +1,47 @@
+using LINGYUN.Abp.IdentityServer.WeChatValidator;
+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 AbpIdentityServerWeChatValidatorModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(builder =>
+ {
+ builder.AddExtensionGrantValidator();
+ });
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+
+ Configure(configuration.GetSection("AuthServer:WeChat"));
+ Configure(configuration.GetSection("WeChat:Signature"));
+
+ context.Services.AddHttpClient(WeChatValidatorConsts.WeChatValidatorClientName, options =>
+ {
+ options.BaseAddress = new System.Uri("https://api.weixin.qq.com/sns/jscode2session");
+ });
+
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpWeChatValidatorOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpWeChatValidatorOptions.cs
new file mode 100644
index 000000000..32cf49f46
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/AbpWeChatValidatorOptions.cs
@@ -0,0 +1,8 @@
+namespace LINGYUN.Abp.IdentityServer
+{
+ public class AbpWeChatValidatorOptions
+ {
+ public string AppId { get; set; }
+ public string AppSecret { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json
new file mode 100644
index 000000000..054ab3e9a
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/en.json
@@ -0,0 +1,9 @@
+{
+ "culture": "en",
+ "texts": {
+ "InvalidGrant:GrantTypeInvalid": "The type of authorization that is not allowed!",
+ "InvalidGrant:WeChatTokenInvalid": "WeChat authentication failed!",
+ "InvalidGrant:WeChatCodeNotFound": "The code obtained when WeChat is logged in is empty or does not exist!",
+ "InvalidGrant:WeChatNotRegister": "User WeChat account not registed!"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json
new file mode 100644
index 000000000..cb5482df5
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/Localization/WeChatValidator/zh-Hans.json
@@ -0,0 +1,9 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "InvalidGrant:GrantTypeInvalid": "不被允许的授权类型!",
+ "InvalidGrant:WeChatTokenInvalid": "微信认证失败!",
+ "InvalidGrant:WeChatCodeNotFound": "微信登录时获取的 code 为空或不存在!",
+ "InvalidGrant:WeChatNotRegister": "用户微信账号未绑定!"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs
new file mode 100644
index 000000000..65a3a53aa
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureMiddleware.cs
@@ -0,0 +1,69 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.IdentityServer
+{
+ public class WeChatSignatureMiddleware : IMiddleware, ITransientDependency
+ {
+ protected WeChatSignatureOptions Options { get; }
+ public WeChatSignatureMiddleware(IOptions options)
+ {
+ Options = options.Value;
+ }
+
+ public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ {
+ if (context.Request.Path.HasValue)
+ {
+ var requestPath = context.Request.Path.Value;
+ if (requestPath.Equals(Options.RequestPath))
+ {
+ var timestamp = context.Request.Query["timestamp"];
+ var nonce = context.Request.Query["nonce"];
+ var signature = context.Request.Query["signature"];
+ var echostr = context.Request.Query["echostr"];
+ var check = CheckWeChatSignature(Options.Token, timestamp, nonce, signature);
+ if (check)
+ {
+ await context.Response.WriteAsync(echostr);
+ return;
+ }
+ throw new AbpException("微信验证不通过");
+ }
+ }
+ await next(context);
+ }
+
+ protected bool CheckWeChatSignature(string token, string timestamp, string nonce, string signature)
+ {
+ var al = new ArrayList();
+ al.Add(token);
+ al.Add(timestamp);
+ al.Add(nonce);
+ al.Sort();
+ string signatureStr = string.Empty;
+ for(int i = 0; i < al.Count; i++)
+ {
+ signatureStr += al[i];
+ }
+ using (var sha1 = new SHA1CryptoServiceProvider())
+ {
+ byte[] bytes_in = Encoding.ASCII.GetBytes(signatureStr);
+ byte[] bytes_out = sha1.ComputeHash(bytes_in);
+ string result = BitConverter.ToString(bytes_out).Replace("-", "");
+ if (result.Equals(signature, StringComparison.CurrentCultureIgnoreCase))
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs
new file mode 100644
index 000000000..76a6f1c8e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatSignatureOptions.cs
@@ -0,0 +1,8 @@
+namespace LINGYUN.Abp.IdentityServer
+{
+ public class WeChatSignatureOptions
+ {
+ public string RequestPath { get; set; }
+ public string Token { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs
new file mode 100644
index 000000000..c4583857e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs
@@ -0,0 +1,119 @@
+using IdentityModel;
+using IdentityServer4.Events;
+using IdentityServer4.Models;
+using IdentityServer4.Services;
+using IdentityServer4.Validation;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer.Localization;
+using Volo.Abp.Security.Claims;
+using IdentityUser = Volo.Abp.Identity.IdentityUser;
+
+namespace LINGYUN.Abp.IdentityServer.WeChatValidator
+{
+ public class WeChatTokenGrantValidator : IExtensionGrantValidator
+ {
+ protected ILogger Logger { get; }
+ protected AbpWeChatValidatorOptions Options { get; }
+ protected IHttpClientFactory HttpClientFactory{ 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 WeChatTokenGrantValidator(
+ IEventService eventService,
+ IHttpClientFactory httpClientFactory,
+ UserManager userManager,
+ IIdentityUserRepository userRepository,
+ SignInManager signInManager,
+ IStringLocalizer stringLocalizer,
+ PhoneNumberTokenProvider phoneNumberTokenProvider,
+ IOptionsSnapshot options,
+ ILogger logger)
+ {
+ Logger = logger;
+ Options = options.Value;
+
+ EventService = eventService;
+ UserManager = userManager;
+ SignInManager = signInManager;
+ Localizer = stringLocalizer;
+ UserRepository = userRepository;
+ HttpClientFactory = httpClientFactory;
+ PhoneNumberTokenProvider = phoneNumberTokenProvider;
+ }
+
+ public string GrantType => WeChatValidatorConsts.WeChatValidatorGrantTypeName;
+
+ 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 wechatCode = raw.Get(WeChatValidatorConsts.WeChatValidatorTokenName);
+ if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace())
+ {
+ Logger.LogWarning("Invalid grant type: wechat code not found");
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:WeChatCodeNotFound"]);
+ return;
+ }
+ var httpClient = HttpClientFactory.CreateClient(WeChatValidatorConsts.WeChatValidatorClientName);
+ var httpRequest = new WeChatTokenRequest
+ {
+ Code = wechatCode,
+ AppId = Options.AppId,
+ Secret = Options.AppSecret,
+ BaseUrl = httpClient.BaseAddress.AbsoluteUri
+ };
+
+ var wechatTokenResponse = await httpClient.RequestWeChatCodeTokenAsync(httpRequest);
+ if (wechatTokenResponse.IsError)
+ {
+ Logger.LogWarning("Authentication failed for token: {0}, reason: invalid token", wechatCode);
+ Logger.LogWarning("WeChat auth failed, error: {0}", wechatTokenResponse.ErrorMessage);
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:WeChatTokenInvalid"]);
+ return;
+ }
+ var currentUser = await UserManager.FindByNameAsync(wechatTokenResponse.OpenId);
+ if(currentUser == null)
+ {
+ Logger.LogWarning("Invalid grant type: wechat openid: {0} not register", wechatTokenResponse.OpenId);
+ context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,
+ Localizer["InvalidGrant:WeChatNotRegister"]);
+ return;
+ }
+ var sub = await UserManager.GetUserIdAsync(currentUser);
+
+ var additionalClaims = new List();
+ if (currentUser.TenantId.HasValue)
+ {
+ additionalClaims.Add(new Claim(AbpClaimTypes.TenantId, currentUser.TenantId?.ToString()));
+ }
+ additionalClaims.Add(new Claim(WeChatValidatorConsts.ClaimTypes.OpenId, wechatTokenResponse.OpenId));
+
+ await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, wechatTokenResponse.OpenId, null));
+ context.Result = new GrantValidationResult(sub,
+ WeChatValidatorConsts.AuthenticationMethods.BasedWeChatAuthentication, additionalClaims.ToArray());
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs
new file mode 100644
index 000000000..bc86ed61e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatValidatorConsts.cs
@@ -0,0 +1,21 @@
+namespace LINGYUN.Abp.IdentityServer.WeChatValidator
+{
+ public class WeChatValidatorConsts
+ {
+ public const string WeChatValidatorClientName = "WeChatValidator";
+
+ public const string WeChatValidatorGrantTypeName = "wechat";
+
+ public const string WeChatValidatorTokenName = "code";
+
+ public class ClaimTypes
+ {
+ public const string OpenId = "wechat-id";
+ }
+
+ public class AuthenticationMethods
+ {
+ public const string BasedWeChatAuthentication = "wca";
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs
new file mode 100644
index 000000000..91d411491
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/Microsoft/AspNetCore/Builder/IdentityServerApplicationBuilderExtensions.cs
@@ -0,0 +1,13 @@
+using LINGYUN.Abp.IdentityServer;
+
+namespace Microsoft.AspNetCore.Builder
+{
+ public static class IdentityServerApplicationBuilderExtensions
+ {
+ public static IApplicationBuilder UseWeChatSignature(this IApplicationBuilder builder)
+ {
+ builder.UseMiddleware();
+ return builder;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/HttpClientTokenRequestExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/HttpClientTokenRequestExtensions.cs
new file mode 100644
index 000000000..169520000
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/HttpClientTokenRequestExtensions.cs
@@ -0,0 +1,32 @@
+using IdentityModel.Client;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Net.Http
+{
+ public static class HttpClientTokenRequestExtensions
+ {
+ public static async Task RequestWeChatCodeTokenAsync(this HttpMessageInvoker client, WeChatTokenRequest request, CancellationToken cancellationToken = default)
+ {
+ var getResuestUrlBuiilder = new StringBuilder();
+ getResuestUrlBuiilder.Append(request.BaseUrl);
+ getResuestUrlBuiilder.AppendFormat("?appid={0}", request.AppId);
+ getResuestUrlBuiilder.AppendFormat("&secret={0}", request.Secret);
+ getResuestUrlBuiilder.AppendFormat("&js_code={0}", request.Code);
+ getResuestUrlBuiilder.Append("&grant_type=authorization_code");
+
+ var getRequest = new HttpRequestMessage(HttpMethod.Get, getResuestUrlBuiilder.ToString());
+ HttpResponseMessage httpResponse;
+ try
+ {
+ httpResponse = await client.SendAsync(getRequest, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ return ProtocolResponse.FromException(ex);
+ }
+ return await ProtocolResponse.FromHttpResponseAsync(httpResponse).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/WeChatTokenRequest.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/WeChatTokenRequest.cs
new file mode 100644
index 000000000..14088f187
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/WeChatTokenRequest.cs
@@ -0,0 +1,10 @@
+namespace System.Net.Http
+{
+ public class WeChatTokenRequest
+ {
+ public string BaseUrl { get; set; }
+ public string AppId { get; set; }
+ public string Secret { get; set; }
+ public string Code { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/WeChatTokenResponse.cs b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/WeChatTokenResponse.cs
new file mode 100644
index 000000000..983a0bc4b
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.IdentityServer.WeChatValidator/System/Net/Http/WeChatTokenResponse.cs
@@ -0,0 +1,48 @@
+using IdentityModel.Client;
+
+namespace System.Net.Http
+{
+ public class WeChatTokenResponse : ProtocolResponse
+ {
+ ///
+ /// 用户唯一标识
+ ///
+ public string OpenId => TryGet("openid");
+ ///
+ /// 会话密钥
+ ///
+ ///
+ /// 仅仅只是要一个openid,这个没多大用吧
+ ///
+ public string SessionKey => TryGet("session_key");
+ ///
+ /// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回
+ ///
+ public string UnionId => TryGet("unionid");
+ ///
+ /// 微信认证成功没有errorcode或者errorcode为0
+ ///
+ public new bool IsError => !ErrorCode.IsNullOrWhiteSpace() && !"0".Equals(ErrorCode);
+ ///
+ /// 错误码
+ ///
+ public string ErrorCode => TryGet("errcode");
+ ///
+ /// 错误信息
+ ///
+ public new string ErrorMessage
+ {
+ get
+ {
+ return ErrorCode switch
+ {
+ "-1" => "系统繁忙,此时请开发者稍候再试",
+ "0" => string.Empty,
+ "40029" => "code 无效",
+ "45011" => "频率限制,每个用户每分钟100次",
+ _ => "未知的异常",
+ };
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs
index 549f249f8..572ab75c3 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs
@@ -10,6 +10,12 @@ namespace LINGYUN.Abp.Notifications.SignalR
typeof(AbpAspNetCoreSignalRModule))]
public class AbpNotificationsSignalRModule : AbpModule
{
-
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.PublishProviders.Add();
+ });
+ }
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublisher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
similarity index 70%
rename from aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublisher.cs
rename to aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
index 8130a659e..79263e96f 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublisher.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
@@ -6,33 +6,36 @@ using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Notifications.SignalR
{
- public class SignalRNotificationPublisher : INotificationPublisher, ISingletonDependency
+ public class SignalRNotificationPublishProvider : NotificationPublishProvider
{
- public ILogger Logger { protected get; set; }
+ public ILogger Logger { protected get; set; }
+
+ public override string Name => "SignalR";
private readonly IOnlineClientManager _onlineClientManager;
private readonly IHubContext _hubContext;
- public SignalRNotificationPublisher(
+ public SignalRNotificationPublishProvider(
IOnlineClientManager onlineClientManager,
- IHubContext hubContext)
+ IHubContext hubContext,
+ IServiceProvider serviceProvider)
+ : base(serviceProvider)
{
_hubContext = hubContext;
_onlineClientManager = onlineClientManager;
- Logger = NullLogger.Instance;
+ Logger = NullLogger.Instance;
}
- public async Task PublishAsync(NotificationInfo notification, IEnumerable userIds)
+ public override async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers)
{
- foreach(var userId in userIds)
+ foreach(var identifier in identifiers)
{
- var onlineClientContext = new OnlineClientContext(notification.TenantId, userId);
+ var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId);
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
foreach (var onlineClient in onlineClients)
{
@@ -49,7 +52,7 @@ namespace LINGYUN.Abp.Notifications.SignalR
}
catch (Exception ex)
{
- Logger.LogWarning("Could not send notifications to user: {0}", userId);
+ Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.csproj
new file mode 100644
index 000000000..4ed83b791
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeChatNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeChatNotificationPublishProvider.cs
new file mode 100644
index 000000000..f98ddfcc6
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeChatNotificationPublishProvider.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Notifications.WeChat
+{
+ public class WeChatNotificationPublishProvider : NotificationPublishProvider
+ {
+ public override string Name => "WeChat";
+
+ public WeChatNotificationPublishProvider(
+ IServiceProvider serviceProvider)
+ : base(serviceProvider)
+ {
+
+ }
+
+ public override async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers)
+ {
+ // step1 默认微信openid绑定的就是username,如果不是,那就根据userid去获取
+
+ // step2 调用微信消息推送接口
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
index ec8c315e2..bc983485c 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
@@ -1,14 +1,40 @@
using LINGYUN.Abp.Notifications.Internal;
using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications
{
public class AbpNotificationModule : AbpModule
{
+
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ AutoAddDefinitionProviders(context.Services);
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient();
}
+
+ private static void AutoAddDefinitionProviders(IServiceCollection services)
+ {
+ var definitionProviders = new List();
+
+ services.OnRegistred(context =>
+ {
+ if (typeof(INotificationDefinitionProvider).IsAssignableFrom(context.ImplementationType))
+ {
+ definitionProviders.Add(context.ImplementationType);
+ }
+ });
+
+ services.Configure(options =>
+ {
+ options.DefinitionProviders.AddIfNotContains(definitionProviders);
+ });
+ }
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs
new file mode 100644
index 000000000..dffacc0bf
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs
@@ -0,0 +1,17 @@
+using Volo.Abp.Collections;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class AbpNotificationOptions
+ {
+ public ITypeList DefinitionProviders { get; }
+
+ public ITypeList PublishProviders { get; }
+
+ public AbpNotificationOptions()
+ {
+ PublishProviders = new TypeList();
+ DefinitionProviders = new TypeList();
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionContext.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionContext.cs
new file mode 100644
index 000000000..d46ea70ef
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionContext.cs
@@ -0,0 +1,9 @@
+namespace LINGYUN.Abp.Notifications
+{
+ public interface INotificationDefinitionContext
+ {
+ NotificationDefinition GetOrNull(string name);
+
+ void Add(params NotificationDefinition[] definitions);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionManager.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionManager.cs
new file mode 100644
index 000000000..87829d683
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionManager.cs
@@ -0,0 +1,15 @@
+using JetBrains.Annotations;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public interface INotificationDefinitionManager
+ {
+ [NotNull]
+ NotificationDefinition Get([NotNull] string name);
+
+ IReadOnlyList GetAll();
+
+ NotificationDefinition GetOrNull(string name);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionProvider.cs
new file mode 100644
index 000000000..7c86ddda0
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionProvider.cs
@@ -0,0 +1,7 @@
+namespace LINGYUN.Abp.Notifications
+{
+ public interface INotificationDefinitionProvider
+ {
+ void Define(INotificationDefinitionContext context);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs
index 180f82d59..2ed1301db 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs
@@ -1,9 +1,27 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications
{
public interface INotificationDispatcher
{
- Task DispatcheAsync(NotificationInfo notification);
+ ///
+ /// 发送通知
+ ///
+ ///
+ ///
+ [Obsolete("Api已过时,请调用 DispatcheAsync(string notificationName, NotificationData data, Guid? tenantId = null)")]
+ Task DispatchAsync(NotificationInfo notification);
+
+ ///
+ /// 发送通知
+ ///
+ /// 通知名称
+ /// 数据
+ /// 租户
+ /// 级别
+ ///
+ Task DispatchAsync(string notificationName, NotificationData data, Guid? tenantId = null,
+ NotificationSeverity notificationSeverity = NotificationSeverity.Info);
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs
new file mode 100644
index 000000000..2819d5a28
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public interface INotificationPublishProvider
+ {
+ string Name { get; }
+
+ Task PublishAsync(NotificationInfo notification, IEnumerable identifiers);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProviderManager.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProviderManager.cs
new file mode 100644
index 000000000..630b932c9
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProviderManager.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public interface INotificationPublishProviderManager
+ {
+ List Providers { get; }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublisher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublisher.cs
deleted file mode 100644
index 1e8411eb9..000000000
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublisher.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace LINGYUN.Abp.Notifications
-{
- public interface INotificationPublisher
- {
- Task PublishAsync(NotificationInfo notification, IEnumerable userIds);
- }
-}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs
index e7d0074e5..dc9f81ca9 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs
@@ -6,9 +6,9 @@ namespace LINGYUN.Abp.Notifications
{
public interface INotificationStore
{
- Task InsertUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName);
+ Task InsertUserSubscriptionAsync(Guid? tenantId, UserIdentifier identifier, string notificationName);
- Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable userIds, string notificationName);
+ Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable identifiers, string notificationName);
Task DeleteUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName);
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
index 1e470ee39..6b5bfa6e0 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
@@ -1,34 +1,107 @@
-using System.Linq;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications.Internal
{
internal class DefaultNotificationDispatcher : INotificationDispatcher
{
+ public ILogger Logger { get; set; }
+
private readonly INotificationStore _notificationStore;
- private readonly INotificationPublisher _notificationPublisher;
+ private readonly INotificationDefinitionManager _notificationDefinitionManager;
+ private readonly INotificationPublishProviderManager _notificationPublishProviderManager;
public DefaultNotificationDispatcher(
INotificationStore notificationStore,
- INotificationPublisher notificationPublisher)
+ INotificationDefinitionManager notificationDefinitionManager,
+ INotificationPublishProviderManager notificationPublishProviderManager)
{
_notificationStore = notificationStore;
- _notificationPublisher = notificationPublisher;
+ _notificationDefinitionManager = notificationDefinitionManager;
+ _notificationPublishProviderManager = notificationPublishProviderManager;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public virtual async Task DispatchAsync(string notificationName, NotificationData data, Guid? tenantId = null,
+ NotificationSeverity notificationSeverity = NotificationSeverity.Info)
+ {
+ // 获取自定义的通知
+ var defineNotification = _notificationDefinitionManager.Get(notificationName);
+
+ var notificationInfo = new NotificationInfo
+ {
+ Name = defineNotification.Name,
+ CreationTime = DateTime.Now,
+ NotificationSeverity = notificationSeverity,
+ NotificationType = defineNotification.NotificationType,
+ TenantId = tenantId,
+ Data = data
+ };
+
+ var providers = Enumerable
+ .Reverse(_notificationPublishProviderManager.Providers);
+
+ if (defineNotification.Providers.Any())
+ {
+ providers = providers.Where(p => defineNotification.Providers.Contains(p.Name));
+ }
+
+ await PublishFromProvidersAsync(providers, notificationInfo);
}
- public async Task DispatcheAsync(NotificationInfo notification)
+ public virtual async Task DispatchAsync(NotificationInfo notification)
+ {
+ // 获取自定义的通知
+ var defineNotification = _notificationDefinitionManager.Get(notification.Name);
+
+ notification.NotificationType = defineNotification.NotificationType;
+ notification.Name = defineNotification.Name;
+
+ var providers = Enumerable
+ .Reverse(_notificationPublishProviderManager.Providers);
+
+ if (defineNotification.Providers.Any())
+ {
+ providers = providers.Where(p => defineNotification.Providers.Contains(p.Name));
+ }
+
+ await PublishFromProvidersAsync(providers, notification);
+ }
+
+ protected async Task PublishFromProvidersAsync(IEnumerable providers,
+ NotificationInfo notificationInfo)
{
// 持久化通知
- await _notificationStore.InsertNotificationAsync(notification);
+ await _notificationStore.InsertNotificationAsync(notificationInfo);
// 获取用户订阅列表
- var userSubscriptions = await _notificationStore.GetSubscriptionsAsync(notification.TenantId, notification.Name);
+ var userSubscriptions = await _notificationStore.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
// 持久化用户通知
- var subscriptionUserIds = userSubscriptions.Select(us => us.UserId);
- await _notificationStore.InsertUserNotificationsAsync(notification, subscriptionUserIds);
+ var subscriptionUserIdentifiers = userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName));
+
+ await _notificationStore.InsertUserNotificationsAsync(notificationInfo,
+ subscriptionUserIdentifiers.Select(u => u.UserId));
+
+ // 发送通知
+ foreach (var provider in providers)
+ {
+ try
+ {
+ await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
+ }
+ catch(Exception ex)
+ {
+ Logger.LogWarning("Send notification error with provider {0}", provider.Name);
+ Logger.LogWarning("Error message:{0}", ex.Message);
- // 发布用户通知
- await _notificationPublisher.PublishAsync(notification, subscriptionUserIds);
+ Logger.LogTrace(ex, "Send notification error with provider {0}", provider.Name);
+ }
+ }
}
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
new file mode 100644
index 000000000..3ccfd9534
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
@@ -0,0 +1,70 @@
+using JetBrains.Annotations;
+using System;
+using System.Collections.Generic;
+using Volo.Abp;
+using Volo.Abp.Localization;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class NotificationDefinition
+ {
+ ///
+ /// 通知名称
+ ///
+ [NotNull]
+ public string Name { get; set; }
+ ///
+ /// 通知显示名称
+ ///
+ [NotNull]
+ public ILocalizableString DisplayName
+ {
+ get => _displayName;
+ set => _displayName = Check.NotNull(value, nameof(value));
+ }
+ private ILocalizableString _displayName;
+ ///
+ /// 通知说明
+ ///
+ [CanBeNull]
+ public ILocalizableString Description { get; set; }
+ ///
+ /// 允许客户端显示订阅
+ ///
+ public bool AllowSubscriptionToClients { get; set; }
+ ///
+ /// 通知类型
+ ///
+ public NotificationType NotificationType { get; set; }
+ ///
+ /// 通知提供者
+ ///
+ public List Providers { get; }
+
+ public NotificationDefinition(
+ string name,
+ ILocalizableString displayName = null,
+ ILocalizableString description = null,
+ NotificationType notificationType = NotificationType.Application,
+ bool allowSubscriptionToClients = false)
+ {
+ Name = name;
+ DisplayName = displayName ?? new FixedLocalizableString(name);
+ Description = description;
+ NotificationType = notificationType;
+ AllowSubscriptionToClients = allowSubscriptionToClients;
+
+ Providers = new List();
+ }
+
+ public virtual NotificationDefinition WithProviders(params string[] providers)
+ {
+ if (!providers.IsNullOrEmpty())
+ {
+ Providers.AddRange(providers);
+ }
+
+ return this;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionContext.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionContext.cs
new file mode 100644
index 000000000..9edf15535
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionContext.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class NotificationDefinitionContext : INotificationDefinitionContext
+ {
+ protected Dictionary Notifications { get; }
+
+ public NotificationDefinitionContext(Dictionary notifications)
+ {
+ Notifications = notifications;
+ }
+
+ public void Add(params NotificationDefinition[] definitions)
+ {
+ if (definitions.IsNullOrEmpty())
+ {
+ return;
+ }
+
+ foreach (var definition in definitions)
+ {
+ Notifications[definition.Name] = definition;
+ }
+ }
+
+ public NotificationDefinition GetOrNull(string name)
+ {
+ return Notifications.GetOrDefault(name);
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs
new file mode 100644
index 000000000..3dde7bc3c
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs
@@ -0,0 +1,75 @@
+using JetBrains.Annotations;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using Volo.Abp;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class NotificationDefinitionManager : INotificationDefinitionManager, ISingletonDependency
+ {
+ protected Lazy> NotificationDefinitions { get; }
+
+ protected AbpNotificationOptions Options { get; }
+
+ protected IServiceProvider ServiceProvider { get; }
+
+ public NotificationDefinitionManager(
+ IOptions options,
+ IServiceProvider serviceProvider)
+ {
+ ServiceProvider = serviceProvider;
+ Options = options.Value;
+
+ NotificationDefinitions = new Lazy>(CreateNotificationDefinitions, true);
+ }
+
+ public virtual NotificationDefinition Get([NotNull] string name)
+ {
+ Check.NotNull(name, nameof(name));
+
+ var notification = GetOrNull(name);
+
+ if (notification == null)
+ {
+ throw new AbpException("Undefined notification: " + name);
+ }
+
+ return notification;
+ }
+
+ public virtual IReadOnlyList GetAll()
+ {
+ return NotificationDefinitions.Value.Values.ToImmutableList();
+ }
+
+ public virtual NotificationDefinition GetOrNull(string name)
+ {
+ return NotificationDefinitions.Value.GetOrDefault(name);
+ }
+
+ protected virtual IDictionary CreateNotificationDefinitions()
+ {
+ var notifications = new Dictionary();
+
+ using (var scope = ServiceProvider.CreateScope())
+ {
+ var providers = Options
+ .DefinitionProviders
+ .Select(p => scope.ServiceProvider.GetRequiredService(p) as INotificationDefinitionProvider)
+ .ToList();
+
+ foreach (var provider in providers)
+ {
+ provider.Define(new NotificationDefinitionContext(notifications));
+ }
+ }
+
+ return notifications;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionProvider.cs
new file mode 100644
index 000000000..f921ae5f4
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionProvider.cs
@@ -0,0 +1,9 @@
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public abstract class NotificationDefinitionProvider : INotificationDefinitionProvider, ITransientDependency
+ {
+ public abstract void Define(INotificationDefinitionContext context);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
new file mode 100644
index 000000000..1f8a7a6a0
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public abstract class NotificationPublishProvider : INotificationPublishProvider, ITransientDependency
+ {
+ public abstract string Name { get; }
+
+ protected IServiceProvider ServiceProvider { get; }
+
+ protected NotificationPublishProvider(IServiceProvider serviceProvider)
+ {
+ ServiceProvider = serviceProvider;
+ }
+
+ public abstract Task PublishAsync(NotificationInfo notification, IEnumerable identifiers);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProviderManager.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProviderManager.cs
new file mode 100644
index 000000000..669f3b678
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProviderManager.cs
@@ -0,0 +1,33 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class NotificationPublishProviderManager : INotificationPublishProviderManager, ISingletonDependency
+ {
+ public List Providers => _lazyProviders.Value;
+
+ protected AbpNotificationOptions Options { get; }
+
+ private readonly Lazy> _lazyProviders;
+
+ public NotificationPublishProviderManager(
+ IServiceProvider serviceProvider,
+ IOptions options)
+ {
+ Options = options.Value;
+
+ _lazyProviders = new Lazy>(
+ () => Options
+ .PublishProviders
+ .Select(type => serviceProvider.GetRequiredService(type) as INotificationPublishProvider)
+ .ToList(),
+ true
+ );
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationSubscriptionInfo.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationSubscriptionInfo.cs
index 0122731fc..b4bcb5f79 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationSubscriptionInfo.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationSubscriptionInfo.cs
@@ -6,6 +6,7 @@ namespace LINGYUN.Abp.Notifications
{
public Guid? TenantId { get; set; }
public Guid UserId { get; set; }
+ public string UserName { get; set; }
public string NotificationName { get; set; }
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/UserIdentifier.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/UserIdentifier.cs
new file mode 100644
index 000000000..a6717897f
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/UserIdentifier.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class UserIdentifier
+ {
+ public Guid UserId { get; set; }
+ public string UserName { get; set; }
+
+ public UserIdentifier(Guid userId, string userName)
+ {
+ UserId = userId;
+ UserName = userName;
+ }
+ }
+}
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
index 9eb0d5c96..04ede37ff 100644
--- 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
@@ -6,13 +6,13 @@
-
-
+
+
-
-
+
+
diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmsValidatorModule.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmsValidatorModule.cs
index 0a3d1975c..9c628fe08 100644
--- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmsValidatorModule.cs
+++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/AbpIdentityServerSmsValidatorModule.cs
@@ -30,7 +30,7 @@ namespace LINGYUN.Abp.IdentityServer
{
options.Resources
.Get()
- .AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/Resources");
+ .AddVirtualJson("/LINGYUN/Abp/IdentityServer/Localization/SmsValidator");
});
}
}
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/SmsValidator/en.json
similarity index 100%
rename from aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/en.json
rename to aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/SmsValidator/en.json
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/SmsValidator/zh-Hans.json
similarity index 100%
rename from aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/Resources/zh-Hans.json
rename to aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.SmsValidator/LINGYUN/Abp/IdentityServer/Localization/SmsValidator/zh-Hans.json
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs
index d7a583b55..3a70048aa 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Subscriptions/SubscribeConsts.cs
@@ -3,5 +3,7 @@
public class SubscribeConsts
{
public const int MaxNotificationNameLength = 100;
+
+ public const int MaxUserNameLength = 128;
}
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
index 0b2cb061e..63fef383c 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
@@ -51,21 +51,18 @@ namespace LINGYUN.Abp.MessageService.EventBus
}
using (CultureHelper.Use(userDefaultCultureName, userDefaultCultureName))
{
+ var userIdentifer = new UserIdentifier(eventData.Entity.Id, eventData.Entity.UserName);
// 订阅用户欢迎消息
await _notificationStore.InsertUserSubscriptionAsync(eventData.Entity.TenantId,
- eventData.Entity.Id, UserNotificationNames.WelcomeToApplication);
+ userIdentifer, UserNotificationNames.WelcomeToApplication);
- var userWelcomeNotifiction = new NotificationInfo
- {
- CreationTime = DateTime.Now,
- Name = UserNotificationNames.WelcomeToApplication,
- NotificationSeverity = NotificationSeverity.Info,
- NotificationType = NotificationType.System,
- TenantId = eventData.Entity.TenantId
- };
- userWelcomeNotifiction.Data.Properties["message"] = L("WelcomeToApplicationFormUser", eventData.Entity.UserName);
+ var userWelcomeNotifictionData = new NotificationData();
- await _notificationDispatcher.DispatcheAsync(userWelcomeNotifiction);
+ // 换成用户名称,而不是用户名
+ userWelcomeNotifictionData.Properties["message"] = L("WelcomeToApplicationFormUser", eventData.Entity.Name);
+
+ await _notificationDispatcher.DispatchAsync(UserNotificationNames.WelcomeToApplication,
+ userWelcomeNotifictionData, eventData.Entity.TenantId);
}
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json
index c39859059..f44750a3b 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/en.json
@@ -7,6 +7,7 @@
"Messages:User:1001": "Users do not receive anonymous comments!",
"Messages:User:1002": "The user has rejected all messages!",
"Messages:User:1003": "The user rejects the message you sent!",
+ "WelcomeToApplicationNotification": "User Welcome Notice",
"WelcomeToApplicationFormUser": "User :{0} welcome to join us!"
}
}
\ No newline at end of file
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json
index 9a326307b..cf9f546ac 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json
@@ -7,6 +7,7 @@
"Messages:User:1001": "用户不接收匿名发言!",
"Messages:User:1002": "用户已拒接所有消息!",
"Messages:User:1003": "用户拒绝您发送的消息!",
+ "WelcomeToApplicationNotification": "用户欢迎通知",
"WelcomeToApplicationFormUser": "用户:{0} 欢迎您的加入!"
}
}
\ No newline at end of file
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs
new file mode 100644
index 000000000..c2c37f881
--- /dev/null
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs
@@ -0,0 +1,24 @@
+using LINGYUN.Abp.MessageService.Localization;
+using LINGYUN.Abp.Notifications;
+using Volo.Abp.Localization;
+using Volo.Abp.Users.Notifications;
+
+namespace LINGYUN.Abp.MessageService.Notifications
+{
+ public class AbpMessageServiceNotificationDefinitionProvider : NotificationDefinitionProvider
+ {
+ public override void Define(INotificationDefinitionContext context)
+ {
+ context.Add(new NotificationDefinition(
+ UserNotificationNames.WelcomeToApplication,
+ L("WelcomeToApplicationNotification"),
+ L("WelcomeToApplicationNotification"),
+ allowSubscriptionToClients: true));
+ }
+
+ protected LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationDispatcher.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationDispatcher.cs
deleted file mode 100644
index a24a3dae8..000000000
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationDispatcher.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using LINGYUN.Abp.Notifications;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Volo.Abp.DependencyInjection;
-
-namespace LINGYUN.Abp.MessageService.Notifications
-{
- public class NotificationDispatcher : INotificationDispatcher, ITransientDependency
- {
- protected INotificationStore NotificationStore { get; }
- protected INotificationPublisher NotificationPublisher { get; }
-
- public NotificationDispatcher(
- INotificationStore notificationStore,
- INotificationPublisher notificationPublisher)
- {
- NotificationStore = notificationStore;
- NotificationPublisher = notificationPublisher;
- }
-
- public virtual async Task DispatcheAsync(NotificationInfo notification)
- {
- var subscribes = await NotificationStore.GetSubscriptionsAsync(notification.TenantId, notification.Name);
- foreach (var subscribe in subscribes)
- {
- await NotificationStore.InsertUserNotificationAsync(notification, subscribe.UserId);
- }
-
- var subscribeUsers = subscribes.Select(s => s.UserId);
- await NotifyAsync(notification, subscribeUsers);
- }
-
- protected virtual async Task NotifyAsync(NotificationInfo notification, IEnumerable userIds)
- {
- await NotificationPublisher.PublishAsync(notification, userIds);
- }
- }
-}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationPublisher.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationPublisher.cs
deleted file mode 100644
index 2288cf3b6..000000000
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationPublisher.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace LINGYUN.Abp.MessageService.Notifications
-{
- class NotificationPublisher
- {
- }
-}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs
index c9de3a3c0..238131f83 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs
@@ -194,14 +194,14 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
[UnitOfWork]
- public async Task InsertUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName)
+ public async Task InsertUserSubscriptionAsync(Guid? tenantId, UserIdentifier identifier, string notificationName)
{
using (var unitOfWork = _unitOfWorkManager.Begin())
{
using (CurrentTenant.Change(tenantId))
{
- var userSubscription = new UserSubscribe(notificationName, userId)
+ var userSubscription = new UserSubscribe(notificationName, identifier.UserId, identifier.UserName)
{
CreationTime = Clock.Now
};
@@ -214,7 +214,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
[UnitOfWork]
- public async Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable userIds, string notificationName)
+ public async Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable identifiers, string notificationName)
{
using (var unitOfWork = _unitOfWorkManager.Begin())
{
@@ -222,9 +222,9 @@ namespace LINGYUN.Abp.MessageService.Notifications
{
var userSubscribes = new List();
- foreach(var userId in userIds)
+ foreach(var identifier in identifiers)
{
- userSubscribes.Add(new UserSubscribe(notificationName, userId));
+ userSubscribes.Add(new UserSubscribe(notificationName, identifier.UserId, identifier.UserName));
}
await UserSubscribeRepository.InsertUserSubscriptionAsync(userSubscribes);
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/UserSubscribe.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/UserSubscribe.cs
index 5c5f03c4c..08ad897e2 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/UserSubscribe.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Subscriptions/UserSubscribe.cs
@@ -6,10 +6,12 @@ namespace LINGYUN.Abp.MessageService.Subscriptions
public class UserSubscribe : Subscribe, IHasCreationTime
{
public virtual Guid UserId { get; set; }
+ public virtual string UserName { get; set; }
protected UserSubscribe() { }
- public UserSubscribe(string notificationName, Guid userId) : base(notificationName)
+ public UserSubscribe(string notificationName, Guid userId, string userName) : base(notificationName)
{
UserId = userId;
+ UserName = userName;
}
}
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs
index 71e42ab07..d93b8a5fd 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs
@@ -49,6 +49,10 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore
b.ToTable(options.TablePrefix + "UserSubscribes", options.Schema);
b.Property(p => p.NotificationName).HasMaxLength(SubscribeConsts.MaxNotificationNameLength).IsRequired();
+ b.Property(p => p.UserName)
+ .HasMaxLength(SubscribeConsts.MaxUserNameLength)
+ .HasDefaultValue("/")// 不是必须的
+ .IsRequired();
b.ConfigureCreationTime();
b.ConfigureMultiTenant();
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreGroupRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreGroupRepository.cs
index 1b1b1e653..e5a674b4c 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreGroupRepository.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreGroupRepository.cs
@@ -29,7 +29,9 @@ namespace LINGYUN.Abp.MessageService.Messages
var groupAdmins = await (from gp in DbContext.Set()
join gpa in DbContext.Set()
on gp.GroupId equals gpa.GroupId
- select gpa).ToListAsync();
+ select gpa)
+ .Distinct()
+ .ToListAsync();
return groupAdmins;
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreMessageRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreMessageRepository.cs
index 6508e1a83..f0e1b29d7 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreMessageRepository.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreMessageRepository.cs
@@ -35,6 +35,7 @@ namespace LINGYUN.Abp.MessageService.Messages
skipCount -= 1;
}
var groupMessages = await DbContext.Set()
+ .Distinct()
.Where(x => x.GroupId.Equals(groupId) && x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderByDescending(x => x.MessageId)
@@ -52,6 +53,7 @@ namespace LINGYUN.Abp.MessageService.Messages
skipCount -= 1;
}
var groupMessages = await DbContext.Set()
+ .Distinct()
.Where(x => x.GroupId.Equals(groupId) && x.CreatorId.Equals(sendUserId) && x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderByDescending(x => x.MessageId)
@@ -77,6 +79,7 @@ namespace LINGYUN.Abp.MessageService.Messages
skipCount -= 1;
}
var userMessages = await DbContext.Set()
+ .Distinct()
.Where(x => x.CreatorId.Equals(sendUserId) && x.ReceiveUserId.Equals(receiveUserId) && x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderByDescending(x => x.MessageId)
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatGroupRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatGroupRepository.cs
index 95cfec605..de852f05c 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatGroupRepository.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Messages/EfCoreUserChatGroupRepository.cs
@@ -38,6 +38,7 @@ namespace LINGYUN.Abp.MessageService.Messages
TenantId = ug.TenantId,
UserId = ug.UserId
})
+ .Distinct()
.AsNoTracking()
.ToListAsync();
return groupUsers;
@@ -73,7 +74,9 @@ namespace LINGYUN.Abp.MessageService.Messages
GroupUserCount = ug.Count(),
MaxUserLength = ug.Key.MaxUserCount,
Name = ug.Key.Name
- }).ToListAsync();
+ })
+ .Distinct()
+ .ToListAsync();
return userGroups;
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs
index 41d5a37b7..c743dee86 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs
@@ -51,8 +51,9 @@ namespace LINGYUN.Abp.MessageService.Notifications
where un.UserId.Equals(userId) && un.ReadStatus.Equals(readState)
orderby n.NotificationId descending
select n)
- .Take(maxResultCount)
- .ToListAsync();
+ .Distinct()
+ .Take(maxResultCount)
+ .ToListAsync();
return userNofitications;
}
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs
index 898701772..66fe146e3 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs
@@ -21,7 +21,10 @@ namespace LINGYUN.Abp.MessageService.Subscriptions
public async Task> GetSubscribesAsync(string notificationName)
{
- var userSubscribes = await DbSet.Where(x => x.NotificationName.Equals(notificationName)).ToListAsync();
+ var userSubscribes = await DbSet
+ .Distinct()
+ .Where(x => x.NotificationName.Equals(notificationName))
+ .ToListAsync();
return userSubscribes;
}
@@ -38,6 +41,7 @@ namespace LINGYUN.Abp.MessageService.Subscriptions
public async Task> GetUserSubscribesAsync(Guid userId)
{
var userSubscribeNames = await DbSet
+ .Distinct()
.Where(x => x.UserId.Equals(userId))
.Select(x => x.NotificationName)
.ToListAsync();
@@ -48,6 +52,7 @@ namespace LINGYUN.Abp.MessageService.Subscriptions
public async Task> GetUserSubscribesAsync(string notificationName)
{
var subscribeUsers = await DbSet
+ .Distinct()
.Where(x => x.NotificationName.Equals(notificationName))
.Select(x => x.UserId)
.ToListAsync();
diff --git a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
index 2e9890ec2..b6736cfe2 100644
--- a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
+++ b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
@@ -40,6 +40,7 @@ namespace AuthServer.Host
typeof(AbpCAPEventBusModule),
typeof(AbpIdentityAspNetCoreModule),
typeof(AbpIdentityServerSmsValidatorModule),
+ typeof(AbpIdentityServerWeChatValidatorModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpIdentityServerEntityFrameworkCoreModule),
@@ -149,6 +150,7 @@ namespace AuthServer.Host
app.UseMultiTenancy();
app.UseIdentityServer();
app.UseAuditing();
+ //app.UseWeChatSignature();
SeedData(context);
}
diff --git a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
index 9259faeec..9c6ba8c5e 100644
--- a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
+++ b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
@@ -34,6 +34,7 @@
+
diff --git a/aspnet-core/services/account/AuthServer.Host/Properties/launchSettings.json b/aspnet-core/services/account/AuthServer.Host/Properties/launchSettings.json
index 581e8d94f..3e2911416 100644
--- a/aspnet-core/services/account/AuthServer.Host/Properties/launchSettings.json
+++ b/aspnet-core/services/account/AuthServer.Host/Properties/launchSettings.json
@@ -11,7 +11,7 @@
"AuthServer.Host": {
"commandName": "Project",
"launchBrowser": false,
- "applicationUrl": "http://localhost:44385",
+ "applicationUrl": "https://localhost:44386;http://localhost:44385",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
index 200f1be92..ab30847b9 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
@@ -1,7 +1,6 @@
using LINGYUN.Abp.Notifications;
using Microsoft.AspNetCore.Mvc;
using System;
-using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc;
@@ -21,20 +20,16 @@ namespace LINGYUN.Abp.MessageService.Controllers
[Route("Send")]
public async Task SendNofitication([FromForm] SendNotification notification)
{
- var notificationInfo = new NotificationInfo
- {
- TenantId = null,
- NotificationSeverity = notification.Severity,
- NotificationType = NotificationType.Application,
- Name = "TestApplicationNotofication",
- CreationTime = Clock.Now
- };
- notificationInfo.Data.Properties["title"] = notification.Title;
- notificationInfo.Data.Properties["message"] = notification.Message;
- notificationInfo.Data.Properties["datetime"] = Clock.Now;
- notificationInfo.Data.Properties["severity"] = notification.Severity;
+ var notificationData = new NotificationData();
+ notificationData.Properties["title"] = notification.Title;
+ notificationData.Properties["message"] = notification.Message;
+ notificationData.Properties["datetime"] = Clock.Now;
+ notificationData.Properties["severity"] = notification.Severity;
+
+ await _notificationDispatcher.DispatchAsync("TestApplicationNotofication", notificationData,
+ notificationSeverity: notification.Severity);
- await _notificationDispatcher.DispatcheAsync(notificationInfo);
+ // await _notificationDispatcher.DispatcheAsync(notificationInfo);
}
}
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs
new file mode 100644
index 000000000..2dcca0a0c
--- /dev/null
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/Notifications/MessageServiceDefinitionProvider.cs
@@ -0,0 +1,24 @@
+using LINGYUN.Abp.MessageService.Localization;
+using LINGYUN.Abp.Notifications;
+using Volo.Abp.Localization;
+
+namespace LINGYUN.Abp.MessageService.LINGYUN.Abp.MessageService.Notifications
+{
+ public class MessageServiceDefinitionProvider : NotificationDefinitionProvider
+ {
+ public override void Define(INotificationDefinitionContext context)
+ {
+ context.Add(new NotificationDefinition(
+ "TestApplicationNotofication",
+ L("TestApplicationNotofication"),
+ L("TestApplicationNotofication"),
+ NotificationType.Application,
+ true));
+ }
+
+ protected LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200609151853_Create-User-Subscription-Column-UserName.Designer.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200609151853_Create-User-Subscription-Column-UserName.Designer.cs
new file mode 100644
index 000000000..1c75e4d1d
--- /dev/null
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200609151853_Create-User-Subscription-Column-UserName.Designer.cs
@@ -0,0 +1,503 @@
+//
+using System;
+using LINGYUN.Abp.MessageService.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
+
+namespace LINGYUN.Abp.MessageService.Migrations
+{
+ [DbContext(typeof(MessageServiceHostMigrationsDbContext))]
+ [Migration("20200609151853_Create-User-Subscription-Column-UserName")]
+ partial class CreateUserSubscriptionColumnUserName
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
+ .HasAnnotation("ProductVersion", "3.1.4")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("Address")
+ .HasColumnType("varchar(256) CHARACTER SET utf8mb4")
+ .HasMaxLength(256);
+
+ b.Property("AllowAnonymous")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowSendMessage")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("CreationTime")
+ .HasColumnName("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnName("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("Description")
+ .HasColumnType("varchar(128) CHARACTER SET utf8mb4")
+ .HasMaxLength(128);
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("LastModificationTime")
+ .HasColumnName("LastModificationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("LastModifierId")
+ .HasColumnName("LastModifierId")
+ .HasColumnType("char(36)");
+
+ b.Property("MaxUserCount")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(20) CHARACTER SET utf8mb4")
+ .HasMaxLength(20);
+
+ b.Property("Notice")
+ .HasColumnType("varchar(64) CHARACTER SET utf8mb4")
+ .HasMaxLength(64);
+
+ b.Property("Tag")
+ .HasColumnType("varchar(512) CHARACTER SET utf8mb4")
+ .HasMaxLength(512);
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Name");
+
+ b.ToTable("AppChatGroups");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroupAdmin", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AllowAddPeople")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowDissolveGroup")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowKickPeople")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowSendNotice")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowSilence")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("IsSuperAdmin")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("LastModifierId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "GroupId");
+
+ b.ToTable("AppChatGroupAdmins");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupChatBlack", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("ShieldUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "GroupId");
+
+ b.ToTable("AppGroupChatBlacks");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("Content")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(1048576);
+
+ b.Property("CreationTime")
+ .HasColumnName("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("MessageId")
+ .HasColumnType("bigint");
+
+ b.Property("SendState")
+ .HasColumnType("tinyint");
+
+ b.Property("SendUserName")
+ .IsRequired()
+ .HasColumnType("varchar(64) CHARACTER SET utf8mb4")
+ .HasMaxLength(64);
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "GroupId");
+
+ b.ToTable("AppGroupMessages");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatBlack", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("ShieldUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AppUserChatBlacks");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatGroup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationTime")
+ .HasColumnName("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnName("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "GroupId", "UserId");
+
+ b.ToTable("AppUserChatGroups");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatSetting", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AllowAddFriend")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowAnonymous")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowReceiveMessage")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AllowSendMessage")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("RequireAddFriendValition")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AppUserChatSettings");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("Content")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(1048576);
+
+ b.Property("CreationTime")
+ .HasColumnName("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("MessageId")
+ .HasColumnType("bigint");
+
+ b.Property("ReceiveUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("SendState")
+ .HasColumnType("tinyint");
+
+ b.Property("SendUserName")
+ .IsRequired()
+ .HasColumnType("varchar(64) CHARACTER SET utf8mb4")
+ .HasMaxLength(64);
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "ReceiveUserId");
+
+ b.ToTable("AppUserMessages");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserSpecialFocus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)");
+
+ b.Property("FocusUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AppUserSpecialFocuss");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationTime")
+ .HasColumnName("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExpirationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("NotificationData")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(1048576);
+
+ b.Property("NotificationId")
+ .HasColumnType("bigint");
+
+ b.Property("NotificationName")
+ .IsRequired()
+ .HasColumnType("varchar(100) CHARACTER SET utf8mb4")
+ .HasMaxLength(100);
+
+ b.Property("NotificationTypeName")
+ .IsRequired()
+ .HasColumnType("varchar(512) CHARACTER SET utf8mb4")
+ .HasMaxLength(512);
+
+ b.Property("Severity")
+ .HasColumnType("tinyint");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NotificationName");
+
+ b.ToTable("AppNotifications");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("NotificationId")
+ .HasColumnType("bigint");
+
+ b.Property("ReadStatus")
+ .HasColumnType("int");
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "UserId", "NotificationId")
+ .HasName("IX_Tenant_User_Notification_Id");
+
+ b.ToTable("AppUserNotifications");
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationTime")
+ .HasColumnName("CreationTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("NotificationName")
+ .IsRequired()
+ .HasColumnType("varchar(100) CHARACTER SET utf8mb4")
+ .HasMaxLength(100);
+
+ b.Property("TenantId")
+ .HasColumnName("TenantId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserName")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("varchar(128) CHARACTER SET utf8mb4")
+ .HasMaxLength(128)
+ .HasDefaultValue("/");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "UserId", "NotificationName")
+ .IsUnique()
+ .HasName("IX_Tenant_User_Notification_Name");
+
+ b.ToTable("AppUserSubscribes");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200609151853_Create-User-Subscription-Column-UserName.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200609151853_Create-User-Subscription-Column-UserName.cs
new file mode 100644
index 000000000..5c109d763
--- /dev/null
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20200609151853_Create-User-Subscription-Column-UserName.cs
@@ -0,0 +1,24 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace LINGYUN.Abp.MessageService.Migrations
+{
+ public partial class CreateUserSubscriptionColumnUserName : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "UserName",
+ table: "AppUserSubscribes",
+ maxLength: 128,
+ nullable: false,
+ defaultValue: "/");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "UserName",
+ table: "AppUserSubscribes");
+ }
+ }
+}
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs
index 8704b41fc..cccaa5a84 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs
@@ -4,6 +4,7 @@ using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.MessageService.Migrations
{
@@ -14,7 +15,8 @@ namespace LINGYUN.Abp.MessageService.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "3.1.3")
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
+ .HasAnnotation("ProductVersion", "3.1.4")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroup", b =>
@@ -478,6 +480,13 @@ namespace LINGYUN.Abp.MessageService.Migrations
b.Property("UserId")
.HasColumnType("char(36)");
+ b.Property("UserName")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("varchar(128) CHARACTER SET utf8mb4")
+ .HasMaxLength(128)
+ .HasDefaultValue("/");
+
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationName")
diff --git a/vueJs/src/views/admin/users/components/UserCreateForm.vue b/vueJs/src/views/admin/users/components/UserCreateForm.vue
index af0f148d0..3312553e8 100644
--- a/vueJs/src/views/admin/users/components/UserCreateForm.vue
+++ b/vueJs/src/views/admin/users/components/UserCreateForm.vue
@@ -141,11 +141,11 @@ export default class extends Vue {
private createUserRules = {
userName: [
{ required: true, message: this.l('userProfile.pleaseInputUserName'), trigger: 'blur' },
- { min: 3, max: 20, message: this.l('global.charLengthRange', { min: 3, max: 20 }), trigger: 'blur' }
+ { min: 3, max: 128, message: this.l('global.charLengthRange', { min: 3, max: 128 }), trigger: 'blur' }
],
name: [
{ required: true, message: this.l('userProfile.pleaseInputName'), trigger: 'blur' },
- { min: 3, max: 50, message: this.l('global.charLengthRange', { min: 3, max: 50 }), trigger: 'blur' }
+ { min: 2, max: 256, message: this.l('global.charLengthRange', { min: 2, max: 256 }), trigger: 'blur' }
],
email: [
{ required: true, message: this.l('userProfile.pleaseInputEmail'), trigger: 'blur' },