diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs new file mode 100644 index 000000000..d20c686f3 --- /dev/null +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs @@ -0,0 +1,61 @@ +using LINGYUN.Abp.Notifications; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc; + +namespace LINGYUN.Abp.MessageService.Controllers +{ + [Route("api/app/notifications")] + public class NotificationController : AbpController + { + private readonly INotificationPublisher _notificationPublisher; + public NotificationController( + INotificationPublisher notificationPublisher) + { + _notificationPublisher = notificationPublisher; + } + + [HttpPost] + [Route("Send")] + public async Task SendNofitication([FromForm] SendNotification notification) + { + var notificationInfo = new NotificationInfo + { + TenantId = null, + NotificationSeverity = NotificationSeverity.Success, + NotificationType = NotificationType.Application, + Id = 164589598456654164, + Name = "TestApplicationNotofication" + }; + notificationInfo.Data.Properties["Title"] = notification.Title; + notificationInfo.Data.Properties["Message"] = notification.Message; + notificationInfo.Data.Properties["DateTime"] = notification.DateTime; + notificationInfo.Data.Properties["Severity"] = notification.Severity; + + await _notificationPublisher.PublishAsync(notificationInfo, new List() { notification.UserId }); + } + } + + public class SendNotification + { + public Guid UserId { get; set; } + public string Title { get; set; } + public DateTime DateTime { get; set; } = DateTime.Now; + public string Message { get; set; } + public NotificationSeverity Severity { get; set; } = NotificationSeverity.Success; + } + + public class TestApplicationNotificationData : NotificationData + { + public object Message + { + get { return this[nameof(Message)]; } + set + { + Properties[nameof(Message)] = value; + } + } + } +} diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj index cc942270a..6068bef78 100644 --- a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj @@ -33,6 +33,7 @@ + diff --git a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs index 31fa0f95c..471488ada 100644 --- a/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs +++ b/aspnet-core/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs @@ -3,14 +3,18 @@ using LINGYUN.Abp.IM.SignalR; using LINGYUN.Abp.MessageService.EntityFrameworkCore; using LINGYUN.Abp.MessageService.MultiTenancy; using LINGYUN.Abp.Notifications.SignalR; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; using Microsoft.OpenApi.Models; using StackExchange.Redis; using System; +using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.MultiTenancy; @@ -28,6 +32,7 @@ using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.MessageService { [DependsOn( + typeof(AbpMessageServiceHttpApiModule), typeof(AbpAspNetCoreMultiTenancyModule), typeof(AbpMessageServiceEntityFrameworkCoreModule), typeof(AbpTenantManagementEntityFrameworkCoreModule), @@ -82,6 +87,30 @@ namespace LINGYUN.Abp.MessageService options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); }); + Configure(options => + { + // 处理signalr某些请求由querystring发送请求令牌 + // https://docs.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-3.1 + options.Authority = configuration["AuthServer:Authority"]; + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + var accessToken = context.Request.Query["access_token"]; + + // If the request is for our hub... + var path = context.HttpContext.Request.Path; + if (!string.IsNullOrEmpty(accessToken) && + (path.StartsWithSegments("/signalr-hubs/notifications"))) + { + // Read the token out of the query string + context.Token = accessToken; + } + return Task.CompletedTask; + } + }; + }); + context.Services.AddAuthentication("Bearer") .AddIdentityServerAuthentication(options => { @@ -98,7 +127,7 @@ namespace LINGYUN.Abp.MessageService { options.Configuration = configuration["RedisCache:ConnectString"]; var instanceName = configuration["RedisCache:RedisPrefix"]; - options.InstanceName = instanceName.IsNullOrEmpty() ? "Platform_Cache" : instanceName; + options.InstanceName = instanceName.IsNullOrEmpty() ? "MessageService_Cache" : instanceName; }); if (!hostingEnvironment.IsDevelopment()) @@ -121,10 +150,14 @@ namespace LINGYUN.Abp.MessageService app.UseAbpRequestLocalization(); //路由 app.UseRouting(); + // 加入自定义中间件 + app.UseMiddleware(); // 认证 app.UseAuthentication(); // jwt app.UseJwtTokenMiddleware(); + // 授权 + app.UseAuthorization(); // 多租户 app.UseMultiTenancy(); // Swagger diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/AbpMessageHub.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs similarity index 96% rename from aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/AbpMessageHub.cs rename to aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs index b1155fcb3..df413d9aa 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/AbpMessageHub.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs @@ -10,12 +10,11 @@ using Volo.Abp.AspNetCore.SignalR; namespace LINGYUN.Abp.IM.SignalR.Hubs { [Authorize] - [HubRoute("messages")] - public class AbpMessageHub : OnlineClientHubBase + public class MessageHub : OnlineClientHubBase { private readonly IMessageStore _messageStore; - public AbpMessageHub( + public MessageHub( IMessageStore messageStore) { _messageStore = messageStore; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs index 65576b017..069d5f199 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs @@ -16,13 +16,13 @@ namespace LINGYUN.Abp.IM.SignalR.Messages private readonly IOnlineClientManager _onlineClientManager; - private readonly IHubContext _hubContext; + private readonly IHubContext _hubContext; private readonly IMessageStore _messageStore; public SignalRMessageSender( IOnlineClientManager onlineClientManager, - IHubContext hubContext, + IHubContext hubContext, IMessageStore messageStore) { _hubContext = hubContext; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/AbpNotificationsHub.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs similarity index 90% rename from aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/AbpNotificationsHub.cs rename to aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs index 1f2b9ba6c..9cfd63d85 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/AbpNotificationsHub.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs @@ -8,8 +8,7 @@ using Volo.Abp.Users; namespace LINGYUN.Abp.Notifications.SignalR.Hubs { [Authorize] - [HubRoute("notifications")] - public class AbpNotificationsHub : OnlineClientHubBase + public class NotificationsHub : OnlineClientHubBase { private INotificationStore _notificationStore; protected INotificationStore NotificationStore => LazyGetRequiredService(ref _notificationStore); diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs index 3a942cbc6..04c341cb6 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs @@ -1,14 +1,19 @@ using LINGYUN.Abp.RealTime.Client; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; using Volo.Abp.AspNetCore.SignalR; +using Volo.Abp.Security.Claims; namespace LINGYUN.Abp.Notifications.SignalR { public abstract class OnlineClientHubBase : AbpHub { + private ICurrentPrincipalAccessor _currentPrincipalAccessor; + protected ICurrentPrincipalAccessor CurrentPrincipalAccessor => LazyGetRequiredService(ref _currentPrincipalAccessor); + private IOnlineClientManager _onlineClientManager; protected IOnlineClientManager OnlineClientManager => LazyGetRequiredService(ref _onlineClientManager); @@ -45,11 +50,16 @@ namespace LINGYUN.Abp.Notifications.SignalR protected virtual IOnlineClient CreateClientForCurrentConnection() { - return new OnlineClient(Context.ConnectionId, GetClientIpAddress(), - CurrentTenant.Id, CurrentUser.Id) + // abp框架没有处理,需要切换一下用户身份令牌.否则无法获取用户信息 + using (CurrentPrincipalAccessor.Change(Context.User)) { - ConnectTime = Clock.Now - }; + return new OnlineClient(Context.ConnectionId, GetClientIpAddress(), + CurrentTenant.Id, CurrentUser.Id) + { + ConnectTime = Clock.Now, + UserName = CurrentUser.UserName + }; + } } protected virtual string GetClientIpAddress() 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/SignalRNotificationPublisher.cs index 534d88e4f..8130a659e 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/SignalRNotificationPublisher.cs @@ -16,11 +16,11 @@ namespace LINGYUN.Abp.Notifications.SignalR private readonly IOnlineClientManager _onlineClientManager; - private readonly IHubContext _hubContext; + private readonly IHubContext _hubContext; public SignalRNotificationPublisher( IOnlineClientManager onlineClientManager, - IHubContext hubContext) + IHubContext hubContext) { _hubContext = hubContext; _onlineClientManager = onlineClientManager; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenMiddleware.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenMiddleware.cs new file mode 100644 index 000000000..c35a6c34f --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenMiddleware.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Microsoft.AspNetCore.Builder +{ + public class SignalRJwtTokenMiddleware : IMiddleware, ITransientDependency + { + public async Task InvokeAsync(HttpContext context, RequestDelegate next) + { + // 仅针对自定义的SignalR hub + if (context.Request.Path.StartsWithSegments("/signalr-hubs/notifications")) + { + if (context.User.Identity?.IsAuthenticated != true) + { + if (context.Request.Query.TryGetValue("access_token", out var accessToken)) + { + context.Request.Headers.Add("Authorization", $"Bearer {accessToken}"); + } + + } + } + await next(context); + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN.Abp.MessageService.HttpApi.csproj b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN.Abp.MessageService.HttpApi.csproj new file mode 100644 index 000000000..fd6a1743a --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN.Abp.MessageService.HttpApi.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp3.1 + + + + + + + + diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiModule.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiModule.cs new file mode 100644 index 000000000..ec2306605 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiModule.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.MessageService +{ + [DependsOn( + typeof(AbpAspNetCoreMvcModule) + )] + public class AbpMessageServiceHttpApiModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpMessageServiceHttpApiModule).Assembly); + }); + } + } +} diff --git a/vueJs/.env.development b/vueJs/.env.development index 00f064f35..18653b2fa 100644 --- a/vueJs/.env.development +++ b/vueJs/.env.development @@ -3,6 +3,8 @@ VUE_APP_BASE_MOCK_API = '/dev-api' VUE_APP_BASE_API = '/api' +#Signalr +VUE_APP_SIGNALR_SERVER = '/signalr-hubs' VUE_APP_BASE_IDENTITY_SERVICE = '/api/identity' diff --git a/vueJs/package-lock.json b/vueJs/package-lock.json index 76d0c5e14..cabe035e0 100644 --- a/vueJs/package-lock.json +++ b/vueJs/package-lock.json @@ -1989,6 +1989,26 @@ } } }, + "@microsoft/signalr": { + "version": "3.1.4", + "resolved": "https://registry.npm.taobao.org/@microsoft/signalr/download/@microsoft/signalr-3.1.4.tgz", + "integrity": "sha1-EILSBjvi0E1LRpnGovsXIyEn/0M=", + "requires": { + "eventsource": "^1.0.7", + "request": "^2.88.0", + "ws": "^6.0.0" + }, + "dependencies": { + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npm.taobao.org/ws/download/ws-6.2.1.tgz?cache=0&sync_timestamp=1589091396925&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fws%2Fdownload%2Fws-6.2.1.tgz", + "integrity": "sha1-RC/fCkftZPWbal2P8TD0dI7VJPs=", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz", @@ -3830,7 +3850,6 @@ "version": "6.12.2", "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.2.tgz?cache=0&sync_timestamp=1587338460514&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.2.tgz", "integrity": "sha1-xinF7O0XuvMUQ3kY0tqIyZ1ZWM0=", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4030,7 +4049,6 @@ "version": "0.2.4", "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz", "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -4076,8 +4094,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", @@ -4105,8 +4122,7 @@ "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz?cache=0&sync_timestamp=1574271725892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-limiter%2Fdownload%2Fasync-limiter-1.0.1.tgz", - "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=", - "dev": true + "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=" }, "async-validator": { "version": "1.8.5", @@ -4119,8 +4135,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", @@ -4168,14 +4183,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.9.1", "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.9.1.tgz", - "integrity": "sha1-fjPY99RJs/ZzzXLeuavcVS2+Uo4=", - "dev": true + "integrity": "sha1-fjPY99RJs/ZzzXLeuavcVS2+Uo4=" }, "axios": { "version": "0.19.2", @@ -4631,7 +4644,6 @@ "version": "1.0.2", "resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -5218,8 +5230,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "cfb": { "version": "1.1.4", @@ -5845,7 +5856,6 @@ "version": "1.0.8", "resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz", "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -6848,7 +6858,6 @@ "version": "1.14.1", "resolved": "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -7175,8 +7184,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegate": { "version": "3.2.0", @@ -7438,7 +7446,6 @@ "version": "0.1.2", "resolved": "https://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -8354,7 +8361,6 @@ "version": "1.0.7", "resolved": "https://registry.npm.taobao.org/eventsource/download/eventsource-1.0.7.tgz", "integrity": "sha1-j7xyyT/NNAiAkLwKTmT0tc7m2NA=", - "dev": true, "requires": { "original": "^1.0.0" } @@ -8588,8 +8594,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz", - "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=", - "dev": true + "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=" }, "extend-shallow": { "version": "3.0.2", @@ -8758,8 +8763,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "faker": { "version": "4.1.0", @@ -8769,8 +8773,7 @@ "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.1.tgz", - "integrity": "sha1-VFFFB3xQFJHjOxXsQIwpQ3bpSuQ=", - "dev": true + "integrity": "sha1-VFFFB3xQFJHjOxXsQIwpQ3bpSuQ=" }, "fast-glob": { "version": "2.2.7", @@ -8789,8 +8792,7 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=", - "dev": true + "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=" }, "fast-levenshtein": { "version": "2.0.6", @@ -9041,8 +9043,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "fork-ts-checker-webpack-plugin": { "version": "3.1.1", @@ -9185,7 +9186,6 @@ "version": "2.3.3", "resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz", "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -9970,7 +9970,6 @@ "version": "0.1.7", "resolved": "https://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -10085,14 +10084,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.3.tgz", "integrity": "sha1-HvievT5JllV2de7ZiTEQ3DUPoIA=", - "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -10458,7 +10455,6 @@ "version": "1.2.0", "resolved": "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -11147,8 +11143,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -11193,8 +11188,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -14375,8 +14369,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { "version": "11.12.0", @@ -14435,14 +14428,12 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz?cache=0&sync_timestamp=1567740732347&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema%2Fdownload%2Fjson-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", - "dev": true + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=" }, "json-stable-stringify": { "version": "1.0.1", @@ -14462,8 +14453,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json3": { "version": "3.3.3", @@ -14508,7 +14498,6 @@ "version": "1.4.1", "resolved": "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -16207,14 +16196,12 @@ "mime-db": { "version": "1.44.0", "resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.44.0.tgz", - "integrity": "sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I=", - "dev": true + "integrity": "sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I=" }, "mime-types": { "version": "2.1.27", "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.27.tgz?cache=0&sync_timestamp=1587700357177&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.27.tgz", "integrity": "sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8=", - "dev": true, "requires": { "mime-db": "1.44.0" } @@ -16720,8 +16707,7 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz", - "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=", - "dev": true + "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=" }, "object-assign": { "version": "4.1.1", @@ -16962,7 +16948,6 @@ "version": "1.0.2", "resolved": "https://registry.npm.taobao.org/original/download/original-1.0.2.tgz", "integrity": "sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8=", - "dev": true, "requires": { "url-parse": "^1.4.3" } @@ -17258,8 +17243,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { "version": "2.2.2", @@ -18223,8 +18207,7 @@ "psl": { "version": "1.8.0", "resolved": "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz", - "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ=", - "dev": true + "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ=" }, "public-encrypt": { "version": "4.0.3", @@ -18275,8 +18258,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz", - "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", - "dev": true + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" }, "q": { "version": "1.5.1", @@ -18286,8 +18268,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz?cache=0&sync_timestamp=1585168614364&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.5.2.tgz", - "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", - "dev": true + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=" }, "query-string": { "version": "4.3.4", @@ -18314,8 +18295,7 @@ "querystringify": { "version": "2.1.1", "resolved": "https://registry.npm.taobao.org/querystringify/download/querystringify-2.1.1.tgz", - "integrity": "sha1-YOWl/WSn+L+k0qsu1v30yFutFU4=", - "dev": true + "integrity": "sha1-YOWl/WSn+L+k0qsu1v30yFutFU4=" }, "ramda": { "version": "0.24.1", @@ -18661,7 +18641,6 @@ "version": "2.88.2", "resolved": "https://registry.npm.taobao.org/request/download/request-2.88.2.tgz?cache=0&sync_timestamp=1581439006948&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frequest%2Fdownload%2Frequest-2.88.2.tgz", "integrity": "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM=", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -18727,8 +18706,7 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, "resize-observer-polyfill": { "version": "1.5.1", @@ -18863,8 +18841,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafer-buffer%2Fdownload%2Fsafer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", - "dev": true + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, "sane": { "version": "4.1.0", @@ -19644,7 +19621,6 @@ "version": "1.16.1", "resolved": "https://registry.npm.taobao.org/sshpk/download/sshpk-1.16.1.tgz", "integrity": "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc=", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -20422,7 +20398,6 @@ "version": "2.5.0", "resolved": "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.5.0.tgz?cache=0&sync_timestamp=1584645708631&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftough-cookie%2Fdownload%2Ftough-cookie-2.5.0.tgz", "integrity": "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI=", - "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -20820,7 +20795,6 @@ "version": "0.6.0", "resolved": "https://registry.npm.taobao.org/tunnel-agent/download/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -20828,8 +20802,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npm.taobao.org/tweetnacl/download/tweetnacl-0.14.5.tgz?cache=0&sync_timestamp=1581364304221&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftweetnacl%2Fdownload%2Ftweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", @@ -21075,7 +21048,6 @@ "version": "4.2.2", "resolved": "https://registry.npm.taobao.org/uri-js/download/uri-js-4.2.2.tgz", "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -21119,7 +21091,6 @@ "version": "1.4.7", "resolved": "https://registry.npm.taobao.org/url-parse/download/url-parse-1.4.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-parse%2Fdownload%2Furl-parse-1.4.7.tgz", "integrity": "sha1-qKg1NejACjFuQDpdtKwbm4U64ng=", - "dev": true, "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -21179,8 +21150,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npm.taobao.org/uuid/download/uuid-3.4.0.tgz?cache=0&sync_timestamp=1588192972951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.4.0.tgz", - "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", - "dev": true + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=" }, "v-click-outside-x": { "version": "3.7.1", @@ -21237,7 +21207,6 @@ "version": "1.10.0", "resolved": "https://registry.npm.taobao.org/verror/download/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", diff --git a/vueJs/package.json b/vueJs/package.json index d0924faf8..b8f34b978 100644 --- a/vueJs/package.json +++ b/vueJs/package.json @@ -15,6 +15,7 @@ "test:unit": "jest --clearCache && vue-cli-service test:unit" }, "dependencies": { + "@microsoft/signalr": "^3.1.4", "@tinymce/tinymce-vue": "^3.2.0", "axios": "^0.19.2", "clipboard": "^2.0.6", diff --git a/vueJs/src/components/Notification/index.vue b/vueJs/src/components/Notification/index.vue new file mode 100644 index 000000000..ba39f0d57 --- /dev/null +++ b/vueJs/src/components/Notification/index.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/vueJs/src/layout/components/Navbar/index.vue b/vueJs/src/layout/components/Navbar/index.vue index 04141c333..9e25830e4 100644 --- a/vueJs/src/layout/components/Navbar/index.vue +++ b/vueJs/src/layout/components/Navbar/index.vue @@ -23,6 +23,7 @@ +