Browse Source

redesign some communication apis

pull/379/head
cKey 4 years ago
parent
commit
e7039ef04e
  1. 69
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs
  2. 5
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalROptions.cs
  3. 121
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs
  4. 6
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Localization/Resources/en.json
  5. 6
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Localization/Resources/zh-Hans.json
  6. 83
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs
  7. 22
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMModule.cs
  8. 3
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs
  9. 9
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Localization/AbpIMResource.cs
  10. 5
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Localization/Resources/en.json
  11. 5
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Localization/Resources/zh-Hans.json
  12. 318
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/ChatMessage.cs
  13. 78
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/LastChatMessage.cs
  14. 8
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSourceTye.cs
  15. 62
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs
  16. 10
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/NotificationDataExtensions.cs
  17. 355
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
  18. 77
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataConverter.cs
  19. 76
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Localization/LocalizableStringInfo.cs
  20. 5
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/MyFriendAppService.cs
  21. 32
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/FriendStore.cs
  22. 22
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IChatDataSeeder.cs
  23. 19
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/Message.cs
  24. 8
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageProcessor.cs
  25. 21
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageStore.cs
  26. 164
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatFriend.cs
  27. 53
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserMessage.cs
  28. 47
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserOnlineChanger.cs
  29. 263
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserChatFriendEventHandler.cs
  30. 16
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Groups/GroupMessage.cs
  31. 4
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Groups/UserGroupStore.cs
  32. 53
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs
  33. 81
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/NotificationTypeConverter.cs
  34. 99
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs
  35. 66
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs
  36. 307
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs
  37. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs
  38. 11
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs
  39. 6
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs
  40. 5
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs
  41. 3
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantSynchronizer.cs
  42. 116
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs
  43. 1
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
  44. 621
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111014501_Add-Base-Type-ExtraProp-To-Notification.Designer.cs
  45. 36
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111014501_Add-Base-Type-ExtraProp-To-Notification.cs
  46. 627
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111080938_Add-Source-Type-To-Chat-Message.Designer.cs
  47. 35
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111080938_Add-Source-Type-To-Chat-Message.cs
  48. 630
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111221335_Add-Field-Static-To-Chat-Friend.Designer.cs
  49. 24
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111221335_Add-Field-Static-To-Chat-Friend.cs
  50. 630
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211112083050_Rename-Field-SendState-To-State.Designer.cs
  51. 33
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211112083050_Rename-Field-SendState-To-State.cs
  52. 866
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs
  53. 164
      aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/SmsNotificationDataMapping_Tests.cs
  54. 154
      aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/WeChatMiniProgramNotificationDataMapping_Tests.cs

69
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs

@ -1,27 +1,42 @@
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken;
using LINGYUN.Abp.IM.SignalR.Messages;
using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.IM.SignalR
{
[DependsOn(
typeof(AbpIMModule),
typeof(AbpRealTimeSignalRModule),
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpIMSignalRModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpIMOptions>(options =>
{
options.Providers.Add<SignalRMessageSenderProvider>();
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
options.MapPath("messages");
});
}
}
}
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken;
using LINGYUN.Abp.IM.Localization;
using LINGYUN.Abp.IM.SignalR.Messages;
using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.IM.SignalR
{
[DependsOn(
typeof(AbpIMModule),
typeof(AbpRealTimeSignalRModule),
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpIMSignalRModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpIMOptions>(options =>
{
options.Providers.Add<SignalRMessageSenderProvider>();
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIMSignalRModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AbpIMResource>()
.AddVirtualJson("/LINGYUN/Abp/IM/SignalR/Localization/Resources");
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
options.MapPath("messages");
});
}
}
}

5
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalROptions.cs

@ -7,6 +7,10 @@
/// </summary>
public string GetChatMessageMethod { get; set; }
/// <summary>
/// 自定义的客户端撤回消息方法名称
/// </summary>
public string ReCallChatMessageMethod { get; set; }
/// <summary>
/// 用户上线接收方法名称
/// </summary>
public string UserOnlineMethod { get; set; }
@ -18,6 +22,7 @@
public AbpIMSignalROptions()
{
GetChatMessageMethod = "get-chat-message";
ReCallChatMessageMethod = "recall-chat-message";
UserOnlineMethod = "on-user-onlined";
UserOfflineMethod = "on-user-offlined";
}

121
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs

@ -1,16 +1,24 @@
using LINGYUN.Abp.IM.Contract;
using LINGYUN.Abp.IM.Groups;
using LINGYUN.Abp.IM.Localization;
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.RealTime;
using LINGYUN.Abp.RealTime.Client;
using LINGYUN.Abp.RealTime.Localization;
using LINGYUN.Abp.RealTime.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.Data;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.IM.SignalR.Hubs
{
@ -21,6 +29,10 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
protected IUserOnlineChanger OnlineChanger => LazyServiceProvider.LazyGetService<IUserOnlineChanger>();
protected ISnowflakeIdrGenerator SnowflakeIdrGenerator => LazyServiceProvider.LazyGetService<ISnowflakeIdrGenerator>();
protected IExceptionToErrorInfoConverter ErrorInfoConverter => LazyServiceProvider.LazyGetService<IExceptionToErrorInfoConverter>();
protected AbpIMSignalROptions Options { get; }
protected IFriendStore FriendStore { get; }
protected IMessageStore MessageStore { get; }
@ -98,32 +110,113 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
[HubMethodName("send")]
public virtual async Task SendAsync(ChatMessage chatMessage)
{
// 持久化
await MessageStore.StoreMessageAsync(chatMessage, cancellationToken: Context.ConnectionAborted);
await SendMessageAsync(Options.GetChatMessageMethod, chatMessage, true);
}
[HubMethodName("recall")]
public virtual async Task ReCallAsync(ChatMessage chatMessage)
{
await Processor.ReCallAsync(chatMessage);
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await SendMessageToGroupAsync(chatMessage);
await SendMessageAsync(
Options.ReCallChatMessageMethod,
ChatMessage.SystemLocalized(
chatMessage.FormUserId,
chatMessage.GroupId,
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(AbpIMResource)),
"Messages:RecallMessage",
new Dictionary<object, object>
{
{ "User", chatMessage.FormUserName }
}),
Clock,
chatMessage.MessageType,
chatMessage.TenantId)
.SetProperty(nameof(ChatMessage.MessageId).ToPascalCase(), chatMessage.MessageId),
callbackException: false);
}
else
{
await SendMessageToUserAsync(chatMessage);
await SendMessageAsync(
Options.ReCallChatMessageMethod,
ChatMessage.SystemLocalized(
chatMessage.ToUserId.Value,
chatMessage.FormUserId,
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(AbpIMResource)),
"Messages:RecallMessage",
new Dictionary<object, object>
{
{ "User", chatMessage.FormUserName }
}),
Clock,
chatMessage.MessageType,
chatMessage.TenantId)
.SetProperty(nameof(ChatMessage.MessageId).ToPascalCase(), chatMessage.MessageId),
callbackException: false);
}
}
[HubMethodName("recall")]
public virtual async Task ReCallAsync(ChatMessage chatMessage)
{
await Processor.ReCallAsync(chatMessage);
}
[HubMethodName("read")]
public virtual async Task ReadAsync(ChatMessage chatMessage)
{
await Processor.ReadAsync(chatMessage);
}
protected virtual async Task SendMessageToGroupAsync(ChatMessage chatMessage)
protected virtual async Task SendMessageAsync(string methodName, ChatMessage chatMessage, bool callbackException = false)
{
// 持久化
try
{
chatMessage.SetProperty(nameof(ChatMessage.IsAnonymous), chatMessage.IsAnonymous);
chatMessage.MessageId = SnowflakeIdrGenerator.Create().ToString();
await MessageStore.StoreMessageAsync(chatMessage);
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await SendMessageToGroupAsync(methodName, chatMessage);
}
else
{
await SendMessageToUserAsync(methodName, chatMessage);
}
}
catch (Exception ex)
{
if (callbackException && ex is IBusinessException)
{
var errorInfo = ErrorInfoConverter.Convert(ex, false);
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await SendMessageToGroupAsync(
methodName,
ChatMessage.System(
chatMessage.FormUserId,
chatMessage.GroupId,
errorInfo.Message,
Clock,
chatMessage.MessageType,
chatMessage.TenantId));
}
else
{
await SendMessageToUserAsync(
methodName,
ChatMessage.System(
chatMessage.ToUserId.Value,
chatMessage.FormUserId,
errorInfo.Message,
Clock,
chatMessage.MessageType,
chatMessage.TenantId));
}
}
}
}
protected virtual async Task SendMessageToGroupAsync(string methodName, ChatMessage chatMessage)
{
var signalRClient = Clients.Group(chatMessage.GroupId);
if (signalRClient == null)
@ -132,10 +225,10 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
return;
}
await signalRClient.SendAsync(Options.GetChatMessageMethod, chatMessage, cancellationToken: Context.ConnectionAborted);
await signalRClient.SendAsync(methodName, chatMessage);
}
protected virtual async Task SendMessageToUserAsync(ChatMessage chatMessage)
protected virtual async Task SendMessageToUserAsync(string methodName, ChatMessage chatMessage)
{
var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.GetValueOrDefault());
var onlineClients = OnlineClientManager.GetAllByContext(onlineClientContext);
@ -150,7 +243,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
continue;
}
await signalRClient.SendAsync(Options.GetChatMessageMethod, chatMessage, cancellationToken: Context.ConnectionAborted);
await signalRClient.SendAsync(methodName, chatMessage);
}
catch (Exception ex)
{

6
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Localization/Resources/en.json

@ -0,0 +1,6 @@
{
"culture": "en",
"texts": {
"Messages:RecallMessage": "{User} cancel a message"
}
}

6
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Localization/Resources/zh-Hans.json

@ -0,0 +1,6 @@
{
"culture": "zh-Hans",
"texts": {
"Messages:RecallMessage": "{User} 撤回了一条消息"
}
}

83
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs

@ -8,7 +8,11 @@ using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.IM.SignalR.Messages
{
@ -35,17 +39,40 @@ namespace LINGYUN.Abp.IM.SignalR.Messages
protected override async Task SendMessageToGroupAsync(ChatMessage chatMessage)
{
var signalRClient = _hubContext.Clients.Group(chatMessage.GroupId);
if (signalRClient == null)
await TrySendMessageToGroupAsync(chatMessage, true);
}
protected override async Task SendMessageToUserAsync(ChatMessage chatMessage)
{
await TrySendMessageToUserAsync(chatMessage, true);
}
protected virtual async Task TrySendMessageToGroupAsync(ChatMessage chatMessage, bool sendingExceptionCallback = true)
{
try
{
Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!");
return;
var signalRClient = _hubContext.Clients.Group(chatMessage.GroupId);
if (signalRClient == null)
{
Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!");
return;
}
await signalRClient.SendAsync(_options.GetChatMessageMethod, chatMessage);
}
catch (Exception ex)
{
Logger.LogWarning("Could not send message to group: {0}", chatMessage.GroupId);
Logger.LogWarning("Send to group message error: {0}", ex.Message);
await signalRClient.SendAsync(_options.GetChatMessageMethod, chatMessage);
if (sendingExceptionCallback)
{
await TrySendBusinessErrorMessage(ex, chatMessage);
}
}
}
protected override async Task SendMessageToUserAsync(ChatMessage chatMessage)
protected virtual async Task TrySendMessageToUserAsync(ChatMessage chatMessage, bool sendingExceptionCallback = true)
{
try
{
@ -65,6 +92,50 @@ namespace LINGYUN.Abp.IM.SignalR.Messages
{
Logger.LogWarning("Could not send message to user: {0}", chatMessage.ToUserId);
Logger.LogWarning("Send to user message error: {0}", ex.Message);
if (sendingExceptionCallback)
{
await TrySendBusinessErrorMessage(ex, chatMessage);
}
}
}
protected virtual async Task TrySendBusinessErrorMessage(Exception ex, ChatMessage chatMessage)
{
if (ex is IBusinessException)
{
var clock = ServiceProvider.LazyGetRequiredService<IClock>();
var errorInfoConverter = ServiceProvider.LazyGetService<IExceptionToErrorInfoConverter>();
if (errorInfoConverter != null)
{
var errorInfo = errorInfoConverter.Convert(ex, false);
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await TrySendMessageToGroupAsync(
ChatMessage.System(
chatMessage.FormUserId,
chatMessage.GroupId,
errorInfo.Message,
clock,
chatMessage.MessageType,
chatMessage.TenantId)
.SetProperty(nameof(ChatMessage.MessageId).ToPascalCase(), chatMessage.MessageId),
sendingExceptionCallback: false);
}
else
{
await TrySendMessageToUserAsync(
ChatMessage.System(
chatMessage.FormUserId,
chatMessage.ToUserId.Value,
errorInfo.Message,
clock,
chatMessage.MessageType,
chatMessage.TenantId)
.SetProperty(nameof(ChatMessage.MessageId).ToPascalCase(), chatMessage.MessageId),
sendingExceptionCallback: false);
}
}
}
}
}

22
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMModule.cs

@ -1,13 +1,31 @@
using LINGYUN.Abp.RealTime;
using LINGYUN.Abp.IM.Localization;
using LINGYUN.Abp.RealTime;
using Volo.Abp.EventBus;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.IM
{
[DependsOn(
typeof(AbpEventBusModule),
typeof(AbpRealTimeModule))]
typeof(AbpRealTimeModule),
typeof(AbpLocalizationModule))]
public class AbpIMModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpIMModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpIMResource>()
.AddVirtualJson("/LINGYUN/Abp/IM/Localization/Resources");
});
}
}
}

3
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs

@ -101,6 +101,7 @@ namespace LINGYUN.Abp.IM.Contract
Guid userId,
Guid friendId,
string remarkName = "",
bool isStatic = false,
CancellationToken cancellationToken = default);
/// <summary>
/// 添加好友请求
@ -114,7 +115,7 @@ namespace LINGYUN.Abp.IM.Contract
Guid? tenantId,
Guid userId,
Guid friendId,
string remarkName = "",
string remarkName = "",
string description = "",
CancellationToken cancellationToken = default);
/// <summary>

9
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Localization/AbpIMResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.IM.Localization
{
[LocalizationResourceName("AbpIM")]
public class AbpIMResource
{
}
}

5
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Localization/Resources/en.json

@ -0,0 +1,5 @@
{
"culture": "en",
"texts": {
}
}

5
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Localization/Resources/zh-Hans.json

@ -0,0 +1,5 @@
{
"culture": "zh-Hans",
"texts": {
}
}

318
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/ChatMessage.cs

@ -1,82 +1,236 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
using Volo.Abp.EventBus;
using Volo.Abp.ObjectExtending;
namespace LINGYUN.Abp.IM.Messages
{
[Serializable]
[EventName("im.message")]
public class ChatMessage : ExtensibleObject
{
/// <summary>
/// 租户
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 群组标识
/// </summary>
public string GroupId { get; set; }
/// <summary>
/// 消息标识
/// </summary>
/// <remarks>
/// 调用者无需关注此字段,将由服务自动生成
/// </remarks>
public string MessageId { get; set; }
/// <summary>
/// 发送者标识
/// </summary>
public Guid FormUserId { get; set; }
/// <summary>
/// 发送者名称
/// </summary>
public string FormUserName { get; set; }
/// <summary>
/// 接收用户标识
/// </summary>
/// <remarks>
/// 设计为可空是为了兼容群聊消息
/// /remarks>
public Guid? ToUserId { get; set; }
/// <summary>
/// 消息内容
/// </summary>
[DisableAuditing]
public string Content { get; set; }
/// <summary>
/// 发送时间
/// </summary>
public DateTime SendTime { get; set; }
/// <summary>
/// 是否匿名发送(存储在扩展字段)
/// </summary>
public bool IsAnonymous { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; } = MessageType.Text;
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = ExtensibleObjectValidator.GetValidationErrors(this, validationContext);
foreach (var result in ValidateReceiver(validationContext))
{
results.Add(result);
}
return results;
}
protected virtual IEnumerable<ValidationResult> ValidateReceiver(ValidationContext validationContext)
{
if (GroupId.IsNullOrWhiteSpace() && !ToUserId.HasValue)
{
yield return new ValidationResult("");
}
}
}
}
using LINGYUN.Abp.RealTime.Localization;
using System;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.EventBus;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.IM.Messages
{
[Serializable]
[EventName("im.message")]
public class ChatMessage : IHasExtraProperties
{
/// <summary>
/// 租户
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 群组标识
/// </summary>
public string GroupId { get; set; }
/// <summary>
/// 消息标识
/// </summary>
/// <remarks>
/// 调用者无需关注此字段,将由服务自动生成
/// </remarks>
public string MessageId { get; set; }
/// <summary>
/// 发送者标识
/// </summary>
public Guid FormUserId { get; set; }
/// <summary>
/// 发送者名称
/// </summary>
public string FormUserName { get; set; }
/// <summary>
/// 接收用户标识
/// </summary>
/// <remarks>
/// 设计为可空是为了兼容群聊消息
/// /remarks>
public Guid? ToUserId { get; set; }
/// <summary>
/// 消息内容
/// </summary>
[DisableAuditing]
public string Content { get; set; }
/// <summary>
/// 发送时间
/// </summary>
public DateTime SendTime { get; set; }
/// <summary>
/// 是否匿名发送(存储在扩展字段)
/// </summary>
public bool IsAnonymous { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; } = MessageType.Text;
public MessageSourceTye Source { get; set; } = MessageSourceTye.User;
public ExtraPropertyDictionary ExtraProperties { get; set; }
public ChatMessage()
{
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
}
public static ChatMessage User(
Guid formUserId,
string formUserName,
Guid toUserId,
string content,
IClock clock,
bool isAnonymous = false,
MessageType type = MessageType.Text,
MessageSourceTye souce = MessageSourceTye.User,
Guid? tenantId = null)
{
return new ChatMessage
{
FormUserId = formUserId,
FormUserName = formUserName,
ToUserId = toUserId,
Content = content,
SendTime = clock.Now,
IsAnonymous = isAnonymous,
MessageType = type,
TenantId = tenantId,
Source = souce,
};
}
public static ChatMessage System(
Guid formUserId,
Guid toUserId,
string content,
IClock clock,
MessageType type = MessageType.Text,
Guid? tenantId = null)
{
return new ChatMessage
{
FormUserId = formUserId,
FormUserName = "system",
ToUserId = toUserId,
Content = content,
SendTime = clock.Now,
IsAnonymous = false,
MessageType = type,
TenantId = tenantId,
Source = MessageSourceTye.System,
}
.SetProperty("L", false);
}
/// <summary>
/// 本地化系统消息
/// 用户消息与群组消息不能使用多语言
/// </summary>
/// <param name="formUserId"></param>
/// <param name="toUserId"></param>
/// <param name="content"></param>
/// <param name="clock"></param>
/// <param name="type"></param>
/// <param name="tenantId"></param>
/// <returns></returns>
public static ChatMessage SystemLocalized(
Guid formUserId,
Guid toUserId,
LocalizableStringInfo content,
IClock clock,
MessageType type = MessageType.Text,
Guid? tenantId = null)
{
return new ChatMessage
{
FormUserId = formUserId,
FormUserName = "system",
ToUserId = toUserId,
Content = "",
SendTime = clock.Now,
IsAnonymous = false,
MessageType = type,
TenantId = tenantId,
Source = MessageSourceTye.System,
}
.SetProperty("L", true)
.SetProperty(nameof(ChatMessage.Content).ToPascalCase(), content);
}
public static ChatMessage System(
Guid formUserId,
string groupId,
string content,
IClock clock,
MessageType type = MessageType.Text,
Guid? tenantId = null)
{
return new ChatMessage
{
FormUserId = formUserId,
FormUserName = "system",
GroupId = groupId,
Content = content,
SendTime = clock.Now,
IsAnonymous = false,
MessageType = type,
TenantId = tenantId,
Source = MessageSourceTye.System,
}
.SetProperty("L", false);
}
/// <summary>
/// 本地化系统消息
/// 用户消息与群组消息不能使用多语言
/// </summary>
/// <param name="formUserId"></param>
/// <param name="groupId"></param>
/// <param name="content"></param>
/// <param name="clock"></param>
/// <param name="type"></param>
/// <param name="tenantId"></param>
/// <returns></returns>
public static ChatMessage SystemLocalized(
Guid formUserId,
string groupId,
LocalizableStringInfo content,
IClock clock,
MessageType type = MessageType.Text,
Guid? tenantId = null)
{
return new ChatMessage
{
FormUserId = formUserId,
FormUserName = "system",
GroupId = groupId,
Content = "",
SendTime = clock.Now,
IsAnonymous = false,
MessageType = type,
TenantId = tenantId,
Source = MessageSourceTye.System,
}
.SetProperty("L", true)
.SetProperty(nameof(ChatMessage.Content).ToPascalCase(), content);
}
public static ChatMessage Group(
Guid formUserId,
string formUserName,
string groupId,
string content,
IClock clock,
bool isAnonymous = false,
MessageType type = MessageType.Text,
MessageSourceTye souce = MessageSourceTye.User,
Guid? tenantId = null)
{
return new ChatMessage
{
FormUserId = formUserId,
FormUserName = formUserName,
GroupId = groupId,
Content = content,
SendTime = clock.Now,
IsAnonymous = isAnonymous,
MessageType = type,
TenantId = tenantId,
Source = souce,
};
}
}
}

78
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/LastChatMessage.cs

@ -1,9 +1,69 @@
namespace LINGYUN.Abp.IM.Messages
{
/// <summary>
/// 上一次通讯消息
/// </summary>
public class LastChatMessage : ChatMessage
{
}
}
using System;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
namespace LINGYUN.Abp.IM.Messages
{
/// <summary>
/// 上一次通讯消息
/// </summary>
public class LastChatMessage : IHasExtraProperties
{
public string AvatarUrl { get; set; }
public string Object { get; set; }
/// <summary>
/// 租户
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 群组标识
/// </summary>
public string GroupId { get; set; }
/// <summary>
/// 消息标识
/// </summary>
/// <remarks>
/// 调用者无需关注此字段,将由服务自动生成
/// </remarks>
public string MessageId { get; set; }
/// <summary>
/// 发送者标识
/// </summary>
public Guid FormUserId { get; set; }
/// <summary>
/// 发送者名称
/// </summary>
public string FormUserName { get; set; }
/// <summary>
/// 接收用户标识
/// </summary>
/// <remarks>
/// 设计为可空是为了兼容群聊消息
/// /remarks>
public string ToUserId { get; set; }
/// <summary>
/// 消息内容
/// </summary>
[DisableAuditing]
public string Content { get; set; }
/// <summary>
/// 发送时间
/// </summary>
public DateTime SendTime { get; set; }
/// <summary>
/// 是否匿名发送(存储在扩展字段)
/// </summary>
public bool IsAnonymous => this.GetProperty(nameof(IsAnonymous), false);
/// <summary>
/// 消息类型
/// </summary>
public MessageType MessageType { get; set; }
public MessageSourceTye Source { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public LastChatMessage()
{
ExtraProperties = new ExtraPropertyDictionary();
}
}
}

8
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSourceTye.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp.IM.Messages
{
public enum MessageSourceTye
{
User = 0,
System = 10,
}
}

62
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs

@ -1,31 +1,31 @@
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken;
using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.SignalR
{
[DependsOn(
typeof(AbpRealTimeSignalRModule),
typeof(AbpNotificationModule),
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpNotificationsSignalRModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<SignalRNotificationPublishProvider>();
options.NotificationDataMappings
.MappingDefault(SignalRNotificationPublishProvider.ProviderName,
data => data);
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
options.MapPath("notifications");
});
}
}
}
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken;
using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.SignalR
{
[DependsOn(
typeof(AbpRealTimeSignalRModule),
typeof(AbpNotificationModule),
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpNotificationsSignalRModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<SignalRNotificationPublishProvider>();
options.NotificationDataMappings
.MappingDefault(SignalRNotificationPublishProvider.ProviderName,
data => data.ToSignalRData());
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
options.MapPath("notifications");
});
}
}
}

10
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/NotificationDataExtensions.cs

@ -0,0 +1,10 @@
namespace LINGYUN.Abp.Notifications.SignalR
{
internal static class NotificationDataExtensions
{
public static NotificationData ToSignalRData(this NotificationData data)
{
return data;
}
}
}

355
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs

@ -1,190 +1,165 @@
using System;
using System.Collections.Generic;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// 通知数据
/// </summary>
/// <remarks>
/// TODO: 2020-10-29 针对不同语言的用户,如果在发布时期就本地化语言是错误的设计
/// 把通知的标题和内容设计为 <see cref="LocalizableStringInfo"/> 让客户端自行本地化
/// </remarks>
[Serializable]
[EventName("notifications")]
public class NotificationData
{
/// <summary>
/// 用来标识是否需要本地化的信息
/// </summary>
public const string LocalizerKey = "localizer";
public virtual string Type => GetType().FullName;
public object this[string key]
{
get
{
if(Properties.TryGetValue(key, out object @obj))
{
return @obj;
}
return null;
}
set { Properties[key] = value; }
}
public Dictionary<string, object> Properties
{
get { return _properties; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
foreach (var keyValue in value)
{
if (!_properties.ContainsKey(keyValue.Key))
{
_properties[keyValue.Key] = keyValue.Value;
}
}
}
}
private readonly Dictionary<string, object> _properties;
public NotificationData()
{
_properties = new Dictionary<string, object>();
TrySetData(LocalizerKey, false);
}
/// <summary>
/// 写入本地化的消息数据
/// </summary>
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="createTime"></param>
/// <param name="formUser"></param>
/// <param name="description"></param>
/// <returns></returns>
public NotificationData WriteLocalizedData(
LocalizableStringInfo title,
LocalizableStringInfo message,
DateTime createTime,
string formUser,
LocalizableStringInfo description = null)
{
TrySetData("title", title);
TrySetData("message", message);
TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, true);
if (description != null)
{
TrySetData("description", description);
}
return this;
}
/// <summary>
/// 写入标准数据
/// </summary>
/// <param name="title">标题</param>
/// <param name="message">内容</param>
/// <param name="createTime">创建时间</param>
/// <param name="formUser">来源用户</param>
/// <param name="description">附加说明</param>
/// <returns></returns>
public NotificationData WriteStandardData(string title, string message, DateTime createTime, string formUser, string description = "")
{
TrySetData("title", title);
TrySetData("message", message);
TrySetData("description", description);
TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, false);
return this;
}
/// <summary>
/// 写入标准数据
/// </summary>
/// <param name="prefix">数据前缀</param>
/// <param name="key">标识</param>
/// <param name="value">数据内容</param>
/// <returns></returns>
public NotificationData WriteStandardData(string prefix, string key, object value)
{
TrySetData(string.Concat(prefix, key), value);
TrySetData(LocalizerKey, false);
return this;
}
/// <summary>
/// 转换为标准数据
/// </summary>
/// <param name="sourceData">原始数据</param>
/// <returns></returns>
public static NotificationData ToStandardData(NotificationData sourceData)
{
var data = new NotificationData();
data.TrySetData("title", sourceData.TryGetData("title"));
data.TrySetData("message", sourceData.TryGetData("message"));
data.TrySetData("description", sourceData.TryGetData("description"));
data.TrySetData("formUser", sourceData.TryGetData("formUser"));
data.TrySetData("createTime", sourceData.TryGetData("createTime"));
data.TrySetData(LocalizerKey, sourceData.TryGetData(LocalizerKey));
return data;
}
/// <summary>
/// 转换为标准数据
/// </summary>
/// <param name="prefix">数据前缀</param>
/// <param name="sourceData">原始数据</param>
/// <returns></returns>
public static NotificationData ToStandardData(string prefix, NotificationData sourceData)
{
var data = ToStandardData(sourceData);
foreach(var property in sourceData.Properties)
{
if (property.Key.StartsWith(prefix))
{
var key = property.Key.Replace(prefix, "");
data.TrySetData(key, property.Value);
}
}
return data;
}
public object TryGetData(string key)
{
if (Properties.TryGetValue(key, out object value))
{
return value;
}
return null;
}
public void TrySetData(string key, object value)
{
if (value != null && !Properties.ContainsKey(key))
{
Properties.Add(key, value);
}
Properties[key] = value;
}
/// <summary>
/// 需要本地化
/// </summary>
/// <returns></returns>
public bool NeedLocalizer()
{
var localizer = TryGetData(LocalizerKey);
if (localizer != null && localizer is bool needLocalizer)
{
return needLocalizer;
}
return false;
}
}
}
using LINGYUN.Abp.RealTime.Localization;
using System;
using Volo.Abp.Data;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// 通知数据
/// </summary>
/// <remarks>
/// TODO: 2020-10-29 针对不同语言的用户,如果在发布时期就本地化语言是错误的设计
/// 把通知的标题和内容设计为 <see cref="LocalizableStringInfo"/> 让客户端自行本地化
/// </remarks>
[Serializable]
[EventName("notifications")]
public class NotificationData : IHasExtraProperties
{
/// <summary>
/// 用来标识是否需要本地化的信息
/// </summary>
public const string LocalizerKey = "L";
public virtual string Type => GetType().FullName;
public object this[string key]
{
get
{
return this.GetProperty(key);
}
set
{
this.SetProperty(key, value);
}
}
public ExtraPropertyDictionary ExtraProperties { get; set; }
public NotificationData()
{
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
TrySetData(LocalizerKey, false);
}
/// <summary>
/// 写入本地化的消息数据
/// </summary>
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="createTime"></param>
/// <param name="formUser"></param>
/// <param name="description"></param>
/// <returns></returns>
public NotificationData WriteLocalizedData(
LocalizableStringInfo title,
LocalizableStringInfo message,
DateTime createTime,
string formUser,
LocalizableStringInfo description = null)
{
TrySetData("title", title);
TrySetData("message", message);
TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, true);
if (description != null)
{
TrySetData("description", description);
}
return this;
}
/// <summary>
/// 写入标准数据
/// </summary>
/// <param name="title">标题</param>
/// <param name="message">内容</param>
/// <param name="createTime">创建时间</param>
/// <param name="formUser">来源用户</param>
/// <param name="description">附加说明</param>
/// <returns></returns>
public NotificationData WriteStandardData(string title, string message, DateTime createTime, string formUser, string description = "")
{
TrySetData("title", title);
TrySetData("message", message);
TrySetData("description", description);
TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, false);
return this;
}
/// <summary>
/// 写入标准数据
/// </summary>
/// <param name="prefix">数据前缀</param>
/// <param name="key">标识</param>
/// <param name="value">数据内容</param>
/// <returns></returns>
public NotificationData WriteStandardData(string prefix, string key, object value)
{
TrySetData(string.Concat(prefix, key), value);
TrySetData(LocalizerKey, false);
return this;
}
/// <summary>
/// 转换为标准数据
/// </summary>
/// <param name="sourceData">原始数据</param>
/// <returns></returns>
public static NotificationData ToStandardData(NotificationData sourceData)
{
var data = new NotificationData();
data.TrySetData("title", sourceData.TryGetData("title"));
data.TrySetData("message", sourceData.TryGetData("message"));
data.TrySetData("description", sourceData.TryGetData("description"));
data.TrySetData("formUser", sourceData.TryGetData("formUser"));
data.TrySetData("createTime", sourceData.TryGetData("createTime"));
data.TrySetData(LocalizerKey, sourceData.TryGetData(LocalizerKey));
return data;
}
/// <summary>
/// 转换为标准数据
/// </summary>
/// <param name="prefix">数据前缀</param>
/// <param name="sourceData">原始数据</param>
/// <returns></returns>
public static NotificationData ToStandardData(string prefix, NotificationData sourceData)
{
var data = ToStandardData(sourceData);
foreach (var property in sourceData.ExtraProperties)
{
if (property.Key.StartsWith(prefix))
{
var key = property.Key.Replace(prefix, "");
data.TrySetData(key, property.Value);
}
}
return data;
}
public object TryGetData(string key)
{
return this.GetProperty(key);
}
public void TrySetData(string key, object value)
{
this.SetProperty(key, value);
}
/// <summary>
/// 需要本地化
/// </summary>
/// <returns></returns>
public bool NeedLocalizer()
{
var localizer = TryGetData(LocalizerKey);
if (localizer != null && localizer is bool needLocalizer)
{
return needLocalizer;
}
return false;
}
}
}

77
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataConverter.cs

@ -1,38 +1,39 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Notifications
{
public class NotificationDataConverter
{
public static NotificationData Convert(NotificationData notificationData)
{
if (notificationData != null)
{
if (notificationData.NeedLocalizer())
{
// 潜在的空对象引用修复
if (notificationData.Properties.TryGetValue("title", out object title) && title != null)
{
var titleObj = JsonConvert.DeserializeObject<LocalizableStringInfo>(title.ToString());
notificationData.TrySetData("title", titleObj);
}
if (notificationData.Properties.TryGetValue("message", out object message) && message != null)
{
var messageObj = JsonConvert.DeserializeObject<LocalizableStringInfo>(message.ToString());
notificationData.TrySetData("message", messageObj);
}
if (notificationData.Properties.TryGetValue("description", out object description) && description != null)
{
notificationData.TrySetData("description", JsonConvert.DeserializeObject<LocalizableStringInfo>(description.ToString()));
}
}
}
else
{
notificationData = new NotificationData();
}
return notificationData;
}
}
}
using LINGYUN.Abp.RealTime.Localization;
using Newtonsoft.Json;
namespace LINGYUN.Abp.Notifications
{
public class NotificationDataConverter
{
public static NotificationData Convert(NotificationData notificationData)
{
if (notificationData != null)
{
if (notificationData.NeedLocalizer())
{
// 潜在的空对象引用修复
if (notificationData.ExtraProperties.TryGetValue("title", out object title) && title != null)
{
var titleObj = JsonConvert.DeserializeObject<LocalizableStringInfo>(title.ToString());
notificationData.TrySetData("title", titleObj);
}
if (notificationData.ExtraProperties.TryGetValue("message", out object message) && message != null)
{
var messageObj = JsonConvert.DeserializeObject<LocalizableStringInfo>(message.ToString());
notificationData.TrySetData("message", messageObj);
}
if (notificationData.ExtraProperties.TryGetValue("description", out object description) && description != null)
{
notificationData.TrySetData("description", JsonConvert.DeserializeObject<LocalizableStringInfo>(description.ToString()));
}
}
}
else
{
notificationData = new NotificationData();
}
return notificationData;
}
}
}

76
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/LocalizableStringInfo.cs → aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Localization/LocalizableStringInfo.cs

@ -1,38 +1,38 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// The notification that needs to be localized
/// </summary>
public class LocalizableStringInfo
{
/// <summary>
/// Resource name
/// </summary>
public string ResourceName { get; }
/// <summary>
/// Properties
/// </summary>
public string Name { get; }
/// <summary>
/// Formatted data
/// </summary>
public Dictionary<object, object> Values { get; }
/// <summary>
/// Instantiate <see cref="LocalizableStringInfo"/>
/// </summary>
/// <param name="resourceName">Resource name</param>
/// <param name="name">Properties</param>
/// <param name="values">Formatted data</param>
public LocalizableStringInfo(
string resourceName,
string name,
Dictionary<object, object> values = null)
{
ResourceName = resourceName;
Name = name;
Values = values;
}
}
}
using System.Collections.Generic;
namespace LINGYUN.Abp.RealTime.Localization
{
/// <summary>
/// The notification that needs to be localized
/// </summary>
public class LocalizableStringInfo
{
/// <summary>
/// Resource name
/// </summary>
public string ResourceName { get; }
/// <summary>
/// Properties
/// </summary>
public string Name { get; }
/// <summary>
/// Formatted data
/// </summary>
public Dictionary<object, object> Values { get; }
/// <summary>
/// Instantiate <see cref="LocalizableStringInfo"/>
/// </summary>
/// <param name="resourceName">Resource name</param>
/// <param name="name">Properties</param>
/// <param name="values">Formatted data</param>
public LocalizableStringInfo(
string resourceName,
string name,
Dictionary<object, object> values = null)
{
ResourceName = resourceName;
Name = name;
Values = values;
}
}
}

5
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/MyFriendAppService.cs

@ -35,7 +35,10 @@ namespace LINGYUN.Abp.MessageService.Chat
{
var friendCard = await UserChatCardRepository.GetMemberAsync(input.FriendId);
await FriendStore.AddMemberAsync(CurrentTenant.Id, CurrentUser.GetId(), input.FriendId, friendCard?.NickName ?? friendCard?.UserName ?? input.FriendId.ToString());
await FriendStore.AddMemberAsync(
CurrentTenant.Id,
CurrentUser.GetId(),
input.FriendId, friendCard?.NickName ?? friendCard?.UserName ?? input.FriendId.ToString());
}
public virtual async Task AddRequestAsync(MyFriendAddRequestDto input)

32
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/FriendStore.cs

@ -58,6 +58,7 @@ namespace LINGYUN.Abp.MessageService.Chat
Guid userId,
Guid friendId,
string remarkName = "",
bool isStatic = false,
CancellationToken cancellationToken = default)
{
using (_currentTenant.Change(tenantId))
@ -66,6 +67,7 @@ namespace LINGYUN.Abp.MessageService.Chat
{
var userFriend = new UserChatFriend(userId, friendId, remarkName);
userFriend.SetStatus(UserFriendStatus.Added);
userFriend.IsStatic = isStatic;
await _userChatFriendRepository.InsertAsync(userFriend);
}
@ -81,9 +83,9 @@ namespace LINGYUN.Abp.MessageService.Chat
[UnitOfWork]
public virtual async Task<UserAddFriendResult> AddRequestAsync(
Guid? tenantId,
Guid userId,
Guid friendId,
Guid? tenantId,
Guid userId,
Guid friendId,
string remarkName = "",
string description = "",
CancellationToken cancellationToken = default)
@ -125,7 +127,7 @@ namespace LINGYUN.Abp.MessageService.Chat
[UnitOfWork]
public virtual async Task AddShieldMemberAsync(
Guid? tenantId,
Guid userId,
Guid userId,
Guid friendId,
CancellationToken cancellationToken = default)
{
@ -146,8 +148,8 @@ namespace LINGYUN.Abp.MessageService.Chat
}
public virtual async Task<int> GetCountAsync(
Guid? tenantId,
Guid userId,
Guid? tenantId,
Guid userId,
string filter = "",
CancellationToken cancellationToken = default)
{
@ -160,10 +162,10 @@ namespace LINGYUN.Abp.MessageService.Chat
public virtual async Task<List<UserFriend>> GetPagedListAsync(
Guid? tenantId,
Guid userId,
string filter = "",
string sorting = nameof(UserFriend.UserId),
int skipCount = 0,
Guid userId,
string filter = "",
string sorting = nameof(UserFriend.UserId),
int skipCount = 0,
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{
@ -191,8 +193,8 @@ namespace LINGYUN.Abp.MessageService.Chat
}
public virtual async Task<UserFriend> GetMemberAsync(
Guid? tenantId,
Guid userId,
Guid? tenantId,
Guid userId,
Guid friendId,
CancellationToken cancellationToken = default)
{
@ -205,7 +207,7 @@ namespace LINGYUN.Abp.MessageService.Chat
[UnitOfWork]
public virtual async Task RemoveMemberAsync(
Guid? tenantId,
Guid? tenantId,
Guid userId,
Guid friendId,
CancellationToken cancellationToken = default)
@ -232,8 +234,8 @@ namespace LINGYUN.Abp.MessageService.Chat
protected virtual async Task ChangeFriendShieldAsync(
Guid? tenantId,
Guid userId,
Guid? tenantId,
Guid userId,
Guid friendId,
bool isBlack = false,
CancellationToken cancellationToken = default)

22
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IChatDataSeeder.cs

@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.Chat
{
public interface IChatDataSeeder
{
Task SeedAsync(
IUserData user);
}
}
using System.Threading.Tasks;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.Chat
{
public interface IChatDataSeeder
{
Task SeedAsync(
IUserData user);
}
}

19
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/Message.cs

@ -29,24 +29,37 @@ namespace LINGYUN.Abp.MessageService.Chat
/// </summary>
public virtual MessageType Type { get; protected set; }
/// <summary>
/// 消息来源
/// </summary>
public virtual MessageSourceTye Source { get; protected set; }
/// <summary>
/// 发送状态
/// </summary>
public virtual MessageState SendState { get; protected set; }
public virtual MessageState State { get; protected set; }
protected Message() { }
public Message(long id, Guid sendUserId, string sendUserName, string content, MessageType type = MessageType.Text)
protected Message(
long id,
Guid sendUserId,
string sendUserName,
string content,
MessageType type = MessageType.Text,
MessageSourceTye source = MessageSourceTye.User,
Guid? tenantId = null)
{
MessageId = id;
CreatorId = sendUserId;
SendUserName = sendUserName;
Content = content;
Type = type;
Source = source;
CreationTime = DateTime.Now;
TenantId = tenantId;
ChangeSendState();
}
public void ChangeSendState(MessageState state = MessageState.Send)
{
SendState = state;
State = state;
}
}
}

8
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageProcessor.cs

@ -30,8 +30,8 @@ namespace LINGYUN.Abp.MessageService.Chat
{
if (!message.GroupId.IsNullOrWhiteSpace())
{
long groupId = long.Parse(message.GroupId);
var groupMessage = await _repository.GetGroupMessageAsync(groupId);
long messageId = long.Parse(message.MessageId);
var groupMessage = await _repository.GetGroupMessageAsync(messageId);
groupMessage.ChangeSendState(MessageState.Read);
await _repository.UpdateGroupMessageAsync(groupMessage);
@ -56,8 +56,8 @@ namespace LINGYUN.Abp.MessageService.Chat
if (!message.GroupId.IsNullOrWhiteSpace())
{
long groupId = long.Parse(message.GroupId);
var groupMessage = await _repository.GetGroupMessageAsync(groupId);
long messageId = long.Parse(message.MessageId);
var groupMessage = await _repository.GetGroupMessageAsync(messageId);
if (hasExpiredMessage(groupMessage))
{
throw new BusinessException(MessageServiceErrorCodes.ExpiredMessageCannotBeReCall)

21
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageStore.cs

@ -64,7 +64,7 @@ namespace LINGYUN.Abp.MessageService.Chat
{
await StoreUserMessageAsync(chatMessage, cancellationToken);
}
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
}
@ -138,6 +138,11 @@ namespace LINGYUN.Abp.MessageService.Chat
{
using (_currentTenant.Change(tenantId))
{
//var messages = await _messageRepository
// .GetLastMessagesAsync(userId, state, sorting, maxResultCount, cancellationToken);
//return _objectMapper.Map<List<LastMessage>, List<LastChatMessage>>(messages);
return await _messageRepository
.GetLastMessagesAsync(userId, state, sorting, maxResultCount, cancellationToken);
}
@ -221,11 +226,12 @@ namespace LINGYUN.Abp.MessageService.Chat
long.Parse(chatMessage.MessageId),
chatMessage.FormUserId,
chatMessage.FormUserName,
chatMessage.ToUserId.Value,
chatMessage.Content,
chatMessage.MessageType);
chatMessage.MessageType,
chatMessage.Source);
message.SendToUser(chatMessage.ToUserId.Value);
message.SetProperty(nameof(ChatMessage.IsAnonymous), chatMessage.IsAnonymous);
message.ExtraProperties.AddIfNotContains(chatMessage.ExtraProperties);
await _messageRepository.InsertUserMessageAsync(message, cancellationToken);
}
@ -258,11 +264,12 @@ namespace LINGYUN.Abp.MessageService.Chat
long.Parse(chatMessage.MessageId),
chatMessage.FormUserId,
chatMessage.FormUserName,
groupId,
chatMessage.Content,
chatMessage.MessageType);
chatMessage.MessageType,
chatMessage.Source);
message.SendToGroup(groupId);
message.SetProperty(nameof(ChatMessage.IsAnonymous), chatMessage.IsAnonymous);
message.ExtraProperties.AddIfNotContains(chatMessage.ExtraProperties);
await _messageRepository.InsertGroupMessageAsync(message, cancellationToken);
}

164
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatFriend.cs

@ -1,80 +1,84 @@
using LINGYUN.Abp.IM.Contract;
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Chat
{
public class UserChatFriend : CreationAuditedAggregateRoot<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 用户标识
/// </summary>
public virtual Guid UserId { get; protected set; }
/// <summary>
/// 好友标识
/// </summary>
public virtual Guid FrientId { get; protected set; }
/// <summary>
/// 已添加黑名单
/// </summary>
public virtual bool Black { get; set; }
/// <summary>
/// 消息免打扰
/// </summary>
public virtual bool DontDisturb { get; set; }
/// <summary>
/// 特别关注
/// </summary>
public virtual bool SpecialFocus { get; set; }
/// <summary>
/// 备注名称
/// </summary>
public virtual string RemarkName { get; set; }
/// <summary>
/// 附加说明
/// </summary>
public virtual string Description { get; set; }
public virtual UserFriendStatus Status { get; protected set; }
protected UserChatFriend()
{
}
public UserChatFriend(
Guid userId,
Guid friendId,
string remarkName = "",
string description = "",
Guid? tenantId = null)
{
UserId = userId;
FrientId = friendId;
RemarkName = remarkName;
TenantId = tenantId;
Description = description;
Status = UserFriendStatus.NeedValidation;
}
public void SetStatus(UserFriendStatus status = UserFriendStatus.NeedValidation)
{
if (Status == UserFriendStatus.NeedValidation && status == UserFriendStatus.Added)
{
// 如果是后续验证通过的需要单独的事件
AddLocalEvent(new UserChatFriendEto
{
TenantId = TenantId,
UserId = UserId,
FrientId = FrientId,
Status = UserFriendStatus.Added
});
}
Status = status;
}
}
}
using LINGYUN.Abp.IM.Contract;
using System;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Chat
{
public class UserChatFriend : CreationAuditedAggregateRoot<long>, IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public virtual Guid? TenantId { get; protected set; }
/// <summary>
/// 用户标识
/// </summary>
public virtual Guid UserId { get; protected set; }
/// <summary>
/// 好友标识
/// </summary>
public virtual Guid FrientId { get; protected set; }
/// <summary>
/// 系统预置
/// </summary>
public virtual bool IsStatic { get; set; }
/// <summary>
/// 已添加黑名单
/// </summary>
public virtual bool Black { get; set; }
/// <summary>
/// 消息免打扰
/// </summary>
public virtual bool DontDisturb { get; set; }
/// <summary>
/// 特别关注
/// </summary>
public virtual bool SpecialFocus { get; set; }
/// <summary>
/// 备注名称
/// </summary>
public virtual string RemarkName { get; set; }
/// <summary>
/// 附加说明
/// </summary>
public virtual string Description { get; set; }
public virtual UserFriendStatus Status { get; protected set; }
protected UserChatFriend()
{
}
public UserChatFriend(
Guid userId,
Guid friendId,
string remarkName = "",
string description = "",
Guid? tenantId = null)
{
UserId = userId;
FrientId = friendId;
RemarkName = remarkName;
TenantId = tenantId;
Description = description;
Status = UserFriendStatus.NeedValidation;
}
public void SetStatus(UserFriendStatus status = UserFriendStatus.NeedValidation)
{
if (Status == UserFriendStatus.NeedValidation && status == UserFriendStatus.Added)
{
// 如果是后续验证通过的需要单独的事件
AddLocalEvent(new UserChatFriendEto
{
TenantId = TenantId,
UserId = UserId,
FrientId = FrientId,
Status = UserFriendStatus.Added
});
}
Status = status;
}
}
}

53
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserMessage.cs

@ -1,25 +1,28 @@
using LINGYUN.Abp.IM.Messages;
using System;
namespace LINGYUN.Abp.MessageService.Chat
{
public class UserMessage : Message
{
/// <summary>
/// 接收用户标识
/// </summary>
public virtual Guid ReceiveUserId { get; set; }
protected UserMessage() { }
public UserMessage(long id, Guid sendUserId, string sendUserName, string content, MessageType type = MessageType.Text)
: base(id, sendUserId, sendUserName, content, type)
{
}
public void SendToUser(Guid receiveUserId)
{
ReceiveUserId = receiveUserId;
}
}
}
using LINGYUN.Abp.IM.Messages;
using System;
namespace LINGYUN.Abp.MessageService.Chat
{
public class UserMessage : Message
{
/// <summary>
/// 接收用户标识
/// </summary>
public virtual Guid ReceiveUserId { get; set; }
protected UserMessage() { }
public UserMessage(
long id,
Guid sendUserId,
string sendUserName,
Guid receiveUserId,
string content,
MessageType type = MessageType.Text,
MessageSourceTye source = MessageSourceTye.User,
Guid? tenantId = null)
: base(id, sendUserId, sendUserName, content, type, source, tenantId)
{
ReceiveUserId = receiveUserId;
}
}
}

47
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserOnlineChanger.cs

@ -0,0 +1,47 @@
using LINGYUN.Abp.IM;
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Timing;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.MessageService.Chat
{
public class UserOnlineChanger : IUserOnlineChanger, ITransientDependency
{
private readonly IClock _clock;
private readonly ICurrentTenant _currentTenant;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IUserChatCardRepository _userChatCardRepository;
public UserOnlineChanger(
IClock clock,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IUserChatCardRepository userChatCardRepository)
{
_clock = clock;
_currentTenant = currentTenant;
_unitOfWorkManager = unitOfWorkManager;
_userChatCardRepository = userChatCardRepository;
}
public virtual async Task ChangeAsync(
Guid? tenantId,
Guid userId,
UserOnlineState state,
CancellationToken cancellationToken = default)
{
using var unitOfWork = _unitOfWorkManager.Begin();
using (_currentTenant.Change(tenantId))
{
var userChatCard = await _userChatCardRepository.FindByUserIdAsync(userId);
userChatCard?.ChangeState(_clock, state);
await unitOfWork.CompleteAsync();
}
}
}
}

263
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserChatFriendEventHandler.cs

@ -1,131 +1,132 @@
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Localization;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus.Local
{
public class UserChatFriendEventHandler :
ILocalEventHandler<EntityCreatedEventData<UserChatFriend>>,
ILocalEventHandler<EntityDeletedEventData<UserChatFriend>>,
ILocalEventHandler<EntityUpdatedEventData<UserChatFriend>>,
ILocalEventHandler<UserChatFriendEto>,
ITransientDependency
{
private IStringLocalizer _stringLocalizer;
private IMessageSender _messageSender;
private INotificationSender _notificationSender;
private IDistributedCache<UserFriendCacheItem> _cache;
private ICurrentUser _currentUser;
public UserChatFriendEventHandler(
ICurrentUser currentUser,
IMessageSender messageSender,
INotificationSender notificationSender,
IDistributedCache<UserFriendCacheItem> cache,
IStringLocalizer<MessageServiceResource> stringLocalizer)
{
_cache = cache;
_currentUser = currentUser;
_messageSender = messageSender;
_stringLocalizer = stringLocalizer;
_notificationSender = notificationSender;
}
public virtual async Task HandleEventAsync(EntityCreatedEventData<UserChatFriend> eventData)
{
switch (eventData.Entity.Status)
{
case IM.Contract.UserFriendStatus.NeedValidation:
await SendFriendValidationNotifierAsync(eventData.Entity);
break;
}
await RemoveUserFriendCacheItemAsync(eventData.Entity.UserId);
}
public virtual async Task HandleEventAsync(EntityDeletedEventData<UserChatFriend> eventData)
{
await RemoveUserFriendCacheItemAsync(eventData.Entity.UserId);
}
public virtual async Task HandleEventAsync(EntityUpdatedEventData<UserChatFriend> eventData)
{
await RemoveUserFriendCacheItemAsync(eventData.Entity.UserId);
}
public virtual async Task HandleEventAsync(UserChatFriendEto eventData)
{
if (eventData.Status == IM.Contract.UserFriendStatus.Added)
{
await SendFriendAddedMessageAsync(eventData.UserId, eventData.FrientId, eventData.TenantId);
}
}
protected virtual async Task SendFriendAddedMessageAsync(Guid userId, Guid friendId, Guid? tenantId = null)
{
// 发送添加好友的第一条消息
var addNewFirendMessage = new ChatMessage
{
TenantId = tenantId,
FormUserId = _currentUser.GetId(), // 本地事件中可以获取到当前用户信息
FormUserName = _currentUser.UserName,
SendTime = DateTime.Now,
MessageType = MessageType.Text,
ToUserId = friendId,
Content = _stringLocalizer["Messages:NewFriend"]
};
await _messageSender.SendMessageAsync(addNewFirendMessage);
}
protected virtual async Task SendFriendValidationNotifierAsync(UserChatFriend userChatFriend)
{
// 发送好友验证通知
var userIdentifer = new UserIdentifier(userChatFriend.FrientId, userChatFriend.RemarkName);
var friendValidationNotifictionData = new NotificationData();
friendValidationNotifictionData
.WriteLocalizedData(
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"Notifications:FriendValidation"),
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"Notifications:RequestAddNewFriend",
new Dictionary<object, object> { { "name", _currentUser.UserName } }),
DateTime.Now,
_currentUser.UserName,
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"Notifications:RequestAddNewFriendDetail",
new Dictionary<object, object> { { "description", userChatFriend.Description } }));
friendValidationNotifictionData.TrySetData("userId", userChatFriend.UserId);
friendValidationNotifictionData.TrySetData("frientId", userChatFriend.FrientId);
await _notificationSender
.SendNofiterAsync(
MessageServiceNotificationNames.IM.FriendValidation,
friendValidationNotifictionData,
userIdentifer,
userChatFriend.TenantId);
}
protected virtual async Task RemoveUserFriendCacheItemAsync(Guid userId)
{
// 移除好友缓存
await _cache.RemoveAsync(UserFriendCacheItem.CalculateCacheKey(userId.ToString()));
}
}
}
using LINGYUN.Abp.IM.Messages;
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.RealTime.Localization;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Localization;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus.Local
{
public class UserChatFriendEventHandler :
ILocalEventHandler<EntityCreatedEventData<UserChatFriend>>,
ILocalEventHandler<EntityDeletedEventData<UserChatFriend>>,
ILocalEventHandler<EntityUpdatedEventData<UserChatFriend>>,
ILocalEventHandler<UserChatFriendEto>,
ITransientDependency
{
private IStringLocalizer _stringLocalizer;
private IMessageSender _messageSender;
private INotificationSender _notificationSender;
private IDistributedCache<UserFriendCacheItem> _cache;
private ICurrentUser _currentUser;
public UserChatFriendEventHandler(
ICurrentUser currentUser,
IMessageSender messageSender,
INotificationSender notificationSender,
IDistributedCache<UserFriendCacheItem> cache,
IStringLocalizer<MessageServiceResource> stringLocalizer)
{
_cache = cache;
_currentUser = currentUser;
_messageSender = messageSender;
_stringLocalizer = stringLocalizer;
_notificationSender = notificationSender;
}
public virtual async Task HandleEventAsync(EntityCreatedEventData<UserChatFriend> eventData)
{
switch (eventData.Entity.Status)
{
case IM.Contract.UserFriendStatus.NeedValidation:
await SendFriendValidationNotifierAsync(eventData.Entity);
break;
}
await RemoveUserFriendCacheItemAsync(eventData.Entity.UserId);
}
public virtual async Task HandleEventAsync(EntityDeletedEventData<UserChatFriend> eventData)
{
await RemoveUserFriendCacheItemAsync(eventData.Entity.UserId);
}
public virtual async Task HandleEventAsync(EntityUpdatedEventData<UserChatFriend> eventData)
{
await RemoveUserFriendCacheItemAsync(eventData.Entity.UserId);
}
public virtual async Task HandleEventAsync(UserChatFriendEto eventData)
{
if (eventData.Status == IM.Contract.UserFriendStatus.Added)
{
await SendFriendAddedMessageAsync(eventData.UserId, eventData.FrientId, eventData.TenantId);
}
}
protected virtual async Task SendFriendAddedMessageAsync(Guid userId, Guid friendId, Guid? tenantId = null)
{
// 发送添加好友的第一条消息
var addNewFirendMessage = new ChatMessage
{
TenantId = tenantId,
FormUserId = _currentUser.GetId(), // 本地事件中可以获取到当前用户信息
FormUserName = _currentUser.UserName,
SendTime = DateTime.Now,
MessageType = MessageType.Text,
ToUserId = friendId,
Content = _stringLocalizer["Messages:NewFriend"]
};
await _messageSender.SendMessageAsync(addNewFirendMessage);
}
protected virtual async Task SendFriendValidationNotifierAsync(UserChatFriend userChatFriend)
{
// 发送好友验证通知
var userIdentifer = new UserIdentifier(userChatFriend.FrientId, userChatFriend.RemarkName);
var friendValidationNotifictionData = new NotificationData();
friendValidationNotifictionData
.WriteLocalizedData(
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"Notifications:FriendValidation"),
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"Notifications:RequestAddNewFriend",
new Dictionary<object, object> { { "name", _currentUser.UserName } }),
DateTime.Now,
_currentUser.UserName,
new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)),
"Notifications:RequestAddNewFriendDetail",
new Dictionary<object, object> { { "description", userChatFriend.Description } }));
friendValidationNotifictionData.TrySetData("userId", userChatFriend.UserId);
friendValidationNotifictionData.TrySetData("frientId", userChatFriend.FrientId);
await _notificationSender
.SendNofiterAsync(
MessageServiceNotificationNames.IM.FriendValidation,
friendValidationNotifictionData,
userIdentifer,
userChatFriend.TenantId);
}
protected virtual async Task RemoveUserFriendCacheItemAsync(Guid userId)
{
// 移除好友缓存
await _cache.RemoveAsync(UserFriendCacheItem.CalculateCacheKey(userId.ToString()));
}
}
}

16
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Groups/GroupMessage.cs

@ -12,12 +12,16 @@ namespace LINGYUN.Abp.MessageService.Groups
public virtual long GroupId { get; protected set; }
protected GroupMessage() { }
public GroupMessage(long id, Guid sendUserId, string sendUserName, string content, MessageType type = MessageType.Text)
: base(id, sendUserId, sendUserName, content, type)
{
}
public void SendToGroup(long groupId)
public GroupMessage(
long id,
Guid sendUserId,
string sendUserName,
long groupId,
string content,
MessageType type = MessageType.Text,
MessageSourceTye source = MessageSourceTye.User,
Guid? tenantId = null)
: base(id, sendUserId, sendUserName, content, type, source, tenantId)
{
GroupId = groupId;
}

4
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Groups/UserGroupStore.cs

@ -55,7 +55,7 @@ namespace LINGYUN.Abp.MessageService.Groups
await _userChatGroupRepository.InsertAsync(userGroup, cancellationToken: cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
}
@ -109,7 +109,7 @@ namespace LINGYUN.Abp.MessageService.Groups
{
await _userChatGroupRepository.RemoveMemberFormGroupAsync(groupId, userId, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
}

53
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs

@ -6,8 +6,10 @@ using LINGYUN.Abp.MessageService.Groups;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.MessageService.Subscriptions;
using LINGYUN.Abp.Notifications;
using System;
using Volo.Abp.AutoMapper;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace LINGYUN.Abp.MessageService.Mapper
{
@ -15,32 +17,26 @@ namespace LINGYUN.Abp.MessageService.Mapper
{
public MessageServiceDomainAutoMapperProfile()
{
//CreateMap<Notification, NotificationInfo>()
// .ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId))
// .ForMember(dto => dto.Name, map => map.MapFrom(src => src.NotificationName))
// .ForMember(dto => dto.Lifetime, map => map.Ignore())
// .ForMember(dto => dto.Type, map => map.MapFrom(src => src.Type))
// .ForMember(dto => dto.Severity, map => map.MapFrom(src => src.Severity))
// .ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) =>
// {
// var dataType = Type.GetType(src.NotificationTypeName);
// var data = JsonConvert.DeserializeObject(src.NotificationData, dataType);
// if(data != null && data is NotificationData notificationData)
// {
// if (notificationData.NeedLocalizer())
// {
// var title = JsonConvert.DeserializeObject<LocalizableStringInfo>(notificationData.TryGetData("title").ToString());
// var message = JsonConvert.DeserializeObject<LocalizableStringInfo>(notificationData.TryGetData("message").ToString());
// notificationData.TrySetData("title", title);
// notificationData.TrySetData("message", message);
// }
// return notificationData;
// }
// return new NotificationData();
// }));
CreateMap<Notification, NotificationInfo>()
.ConvertUsing<NotificationTypeConverter>();
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId))
.ForMember(dto => dto.Name, map => map.MapFrom(src => src.NotificationName))
.ForMember(dto => dto.Lifetime, map => map.Ignore())
.ForMember(dto => dto.Type, map => map.MapFrom(src => src.Type))
.ForMember(dto => dto.Severity, map => map.MapFrom(src => src.Severity))
.ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) =>
{
var dataType = Type.GetType(src.NotificationTypeName);
var data = Activator.CreateInstance(dataType);
if (data is NotificationData notificationData)
{
notificationData.ExtraProperties = src.ExtraProperties;
return notificationData;
}
return new NotificationData();
}));
//CreateMap<Notification, NotificationInfo>()
// .ConvertUsing<NotificationTypeConverter>();
CreateMap<UserSubscribe, NotificationSubscriptionInfo>();
@ -53,10 +49,6 @@ namespace LINGYUN.Abp.MessageService.Mapper
.ForMember(dto => dto.ToUserId, map => map.MapFrom(src => src.ReceiveUserId))
.Ignore(dto => dto.GroupId);
CreateMessageMap<UserMessage, LastChatMessage>()
.ForMember(dto => dto.ToUserId, map => map.MapFrom(src => src.ReceiveUserId))
.Ignore(dto => dto.GroupId);
CreateMap<ChatGroup, Group>()
.ForMember(g => g.Id, map => map.MapFrom(src => src.GroupId.ToString()))
.ForMember(g => g.MaxUserLength, map => map.MapFrom(src => src.MaxUserCount))
@ -74,8 +66,9 @@ namespace LINGYUN.Abp.MessageService.Mapper
.ForMember(dto => dto.FormUserName, map => map.MapFrom(src => src.SendUserName))
.ForMember(dto => dto.SendTime, map => map.MapFrom(src => src.CreationTime))
.ForMember(dto => dto.MessageType, map => map.MapFrom(src => src.Type))
.ForMember(dto => dto.Source, map => map.MapFrom(src => src.Source))
.ForMember(dto => dto.IsAnonymous, map => map.MapFrom(src => src.GetProperty(nameof(ChatMessage.IsAnonymous), false)))
.MapExtraProperties();
.MapExtraProperties(MappingPropertyDefinitionChecks.None);
}
}
}

81
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/NotificationTypeConverter.cs

@ -1,41 +1,40 @@
using AutoMapper;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using Newtonsoft.Json;
using System;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.MessageService.Mapper
{
public class NotificationTypeConverter : ITypeConverter<Notification, NotificationInfo>, ISingletonDependency
{
public NotificationInfo Convert(Notification source, NotificationInfo destination, ResolutionContext context)
{
destination = new NotificationInfo
{
Name = source.NotificationName,
Type = source.Type,
Severity = source.Severity,
CreationTime = source.CreationTime,
TenantId = source.TenantId
};
destination.SetId(source.NotificationId);
var dataType = Type.GetType(source.NotificationTypeName);
Check.NotNull(dataType, source.NotificationTypeName);
var data = JsonConvert.DeserializeObject(source.NotificationData, dataType);
if (data != null && data is NotificationData notificationData)
{
destination.Data = NotificationDataConverter.Convert(notificationData);
}
else
{
destination.Data = new NotificationData();
destination.Data.TrySetData("data", source.NotificationData);
}
return destination;
}
}
}
using AutoMapper;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using System;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.MessageService.Mapper
{
public class NotificationTypeConverter : ITypeConverter<Notification, NotificationInfo>, ISingletonDependency
{
public NotificationInfo Convert(Notification source, NotificationInfo destination, ResolutionContext context)
{
destination = new NotificationInfo
{
Name = source.NotificationName,
Type = source.Type,
Severity = source.Severity,
CreationTime = source.CreationTime,
TenantId = source.TenantId
};
destination.SetId(source.NotificationId);
var dataType = Type.GetType(source.NotificationTypeName);
Check.NotNull(dataType, source.NotificationTypeName);
var data = Activator.CreateInstance(dataType);
if (data != null && data is NotificationData notificationData)
{
notificationData.ExtraProperties = source.ExtraProperties;
destination.Data = NotificationDataConverter.Convert(notificationData);
}
else
{
destination.Data = new NotificationData();
destination.Data.ExtraProperties = source.ExtraProperties;
}
return destination;
}
}
}

99
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/Notification.cs

@ -1,40 +1,59 @@
using LINGYUN.Abp.Notifications;
using System;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Notifications
{
public class Notification : Entity<long>, IMultiTenant, IHasCreationTime
{
public virtual Guid? TenantId { get; protected set; }
public virtual NotificationSeverity Severity { get; protected set; }
public virtual NotificationType Type { get; set; }
public virtual long NotificationId { get; protected set; }
public virtual string NotificationName { get; protected set; }
public virtual string NotificationData { get; protected set; }
public virtual string NotificationTypeName { get; protected set; }
public virtual DateTime? ExpirationTime { get; set; }
public virtual DateTime CreationTime { get; set; }
protected Notification(){}
public Notification(long id)
{
Id = id;
}
public Notification(long id, string name, string dataType, string data,
NotificationSeverity severity = NotificationSeverity.Info,
Guid? tenantId = null)
{
NotificationId = id;
Severity = severity;
NotificationName = name;
NotificationData = data;
NotificationTypeName = dataType;
Type = NotificationType.Application;
TenantId = tenantId;
}
}
}
using LINGYUN.Abp.Notifications;
using System;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.MessageService.Notifications
{
public class Notification : Entity<long>, IMultiTenant, IHasCreationTime, IHasExtraProperties
{
public virtual Guid? TenantId { get; protected set; }
public virtual NotificationSeverity Severity { get; protected set; }
public virtual NotificationType Type { get; set; }
public virtual long NotificationId { get; protected set; }
public virtual string NotificationName { get; protected set; }
public virtual string NotificationTypeName { get; protected set; }
public virtual DateTime? ExpirationTime { get; set; }
public virtual DateTime CreationTime { get; set; }
public virtual ExtraPropertyDictionary ExtraProperties { get; protected set; }
protected Notification()
{
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
}
public Notification(long id) : this()
{
Id = id;
}
public Notification(
long id,
string name,
string dataType,
NotificationData data,
NotificationSeverity severity = NotificationSeverity.Info,
Guid? tenantId = null) : this()
{
NotificationId = id;
Severity = severity;
NotificationName = name;
NotificationTypeName = dataType;
Type = NotificationType.Application;
TenantId = tenantId;
SetData(data);
}
public void SetData(NotificationData data)
{
foreach (var property in data.ExtraProperties)
{
this.SetProperty(property.Key, property.Value);
}
}
}
}

66
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs

@ -7,7 +7,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Timing;
@ -25,8 +24,6 @@ namespace LINGYUN.Abp.MessageService.Notifications
private readonly ICurrentTenant _currentTenant;
private readonly IJsonSerializer _jsonSerializer;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly INotificationRepository _notificationRepository;
@ -39,7 +36,6 @@ namespace LINGYUN.Abp.MessageService.Notifications
IClock clock,
IObjectMapper objectMapper,
ICurrentTenant currentTenant,
IJsonSerializer jsonSerializer,
IUnitOfWorkManager unitOfWorkManager,
INotificationRepository notificationRepository,
IUserSubscribeRepository userSubscribeRepository,
@ -49,7 +45,6 @@ namespace LINGYUN.Abp.MessageService.Notifications
_clock = clock;
_objectMapper = objectMapper;
_currentTenant = currentTenant;
_jsonSerializer = jsonSerializer;
_unitOfWorkManager = unitOfWorkManager;
_notificationRepository = notificationRepository;
_userSubscribeRepository = userSubscribeRepository;
@ -57,9 +52,9 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
public virtual async Task ChangeUserNotificationReadStateAsync(
Guid? tenantId,
Guid? tenantId,
Guid userId,
long notificationId,
long notificationId,
NotificationReadState readState,
CancellationToken cancellationToken = default)
{
@ -72,7 +67,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
notification.ChangeReadState(readState);
await _userNotificationRepository.UpdateAsync(notification);
await unitOfWork.SaveChangesAsync();
await unitOfWork.CompleteAsync();
}
}
}
@ -87,7 +82,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
var notify = await _notificationRepository.GetByIdAsync(notification.GetId(), cancellationToken);
await _notificationRepository.DeleteAsync(notify.Id, cancellationToken: cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
@ -99,7 +94,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
{
await _notificationRepository.DeleteExpritionAsync(batchCount, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
@ -117,7 +112,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userNotificationRepository
.DeleteAsync(notify.Id, cancellationToken: cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
@ -132,13 +127,13 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userSubscribeRepository
.DeleteUserSubscriptionAsync(notificationName, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
public virtual async Task DeleteUserSubscriptionAsync(
Guid? tenantId,
Guid userId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default)
{
@ -150,12 +145,12 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userSubscribeRepository
.DeleteAsync(userSubscribe.Id, cancellationToken: cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
public virtual async Task DeleteUserSubscriptionAsync(
Guid? tenantId,
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default)
@ -166,12 +161,12 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userSubscribeRepository
.DeleteUserSubscriptionAsync(notificationName, identifiers.Select(ids => ids.UserId), cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
public virtual async Task<NotificationInfo> GetNotificationOrNullAsync(
Guid? tenantId,
Guid? tenantId,
long notificationId,
CancellationToken cancellationToken = default)
{
@ -185,7 +180,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
public virtual async Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid? tenantId,
string notificationName,
IEnumerable<UserIdentifier> identifiers = null,
CancellationToken cancellationToken = default)
@ -262,7 +257,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
public virtual async Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default)
{
@ -317,11 +312,12 @@ namespace LINGYUN.Abp.MessageService.Notifications
using (_currentTenant.Change(notification.TenantId))
{
var notify = new Notification(
notification.GetId(),
notification.GetId(),
notification.Name,
notification.Data.GetType().AssemblyQualifiedName,
_jsonSerializer.Serialize(notification.Data),
notification.Severity, notification.TenantId)
notification.Data,
notification.Severity,
notification.TenantId)
{
CreationTime = _clock.Now,
Type = notification.Type,
@ -331,14 +327,14 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _notificationRepository.InsertAsync(notify, cancellationToken: cancellationToken);
notification.Id = notify.NotificationId.ToString();
notification.SetId(notify.NotificationId);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
public virtual async Task InsertUserNotificationAsync(
NotificationInfo notification,
NotificationInfo notification,
Guid userId,
CancellationToken cancellationToken = default)
{
@ -349,7 +345,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userNotificationRepository
.InsertAsync(userNotification, cancellationToken: cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
@ -371,12 +367,12 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userSubscribeRepository
.InsertAsync(userSubscription, cancellationToken: cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
public virtual async Task InsertUserSubscriptionAsync(
Guid? tenantId,
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default)
@ -394,23 +390,23 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userSubscribeRepository
.InsertUserSubscriptionAsync(userSubscribes, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
public virtual async Task<bool> IsSubscribedAsync(
Guid? tenantId,
Guid userId,
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default)
{
using (_currentTenant.Change(tenantId))
return await _userSubscribeRepository
.UserSubscribeExistsAysnc(notificationName, userId, cancellationToken);
return await _userSubscribeRepository
.UserSubscribeExistsAysnc(notificationName, userId, cancellationToken);
}
public virtual async Task InsertUserNotificationsAsync(
NotificationInfo notification,
NotificationInfo notification,
IEnumerable<Guid> userIds,
CancellationToken cancellationToken = default)
{
@ -431,7 +427,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
await _userNotificationRepository
.InsertUserNotificationsAsync(userNofitications, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
await unitOfWork.CompleteAsync(cancellationToken);
}
}
}

307
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs

@ -2,15 +2,22 @@
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using LINGYUN.Abp.MessageService.Groups;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Json.SystemTextJson.JsonConverters;
namespace LINGYUN.Abp.MessageService.Chat
{
@ -45,7 +52,8 @@ namespace LINGYUN.Abp.MessageService.Chat
var groupMessages = await (await GetDbContextAsync()).Set<GroupMessage>()
.Distinct()
.Where(x => x.GroupId.Equals(groupId))
.WhereIf(type != null, x => x.Type.Equals(type))
.Where(x => x.State == MessageState.Send || x.State == MessageState.Read)
.WhereIf(type.HasValue, x => x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderBy(sorting ?? nameof(GroupMessage.MessageId))
.PageBy(skipCount, maxResultCount)
@ -64,7 +72,8 @@ namespace LINGYUN.Abp.MessageService.Chat
var groupMessagesCount = await (await GetDbContextAsync()).Set<GroupMessage>()
.Distinct()
.Where(x => x.GroupId.Equals(groupId))
.WhereIf(type != null, x => x.Type.Equals(type))
.Where(x => x.State == MessageState.Send || x.State == MessageState.Read)
.WhereIf(type.HasValue, x => x.Type.Equals(type))
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.LongCountAsync(GetCancellationToken(cancellationToken));
return groupMessagesCount;
@ -153,37 +162,271 @@ namespace LINGYUN.Abp.MessageService.Chat
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{
sorting ??= $"{nameof(LastChatMessage.SendTime)} DESC";
var dbContext = await GetDbContextAsync();
var groupMsgQuery = dbContext.Set<UserMessage>()
.Where(msg => msg.ReceiveUserId == userId)
.WhereIf(state.HasValue, x => x.SendState == state)
.GroupBy(msg => new { msg.CreatorId, msg.ReceiveUserId })
.Select(msg => new
#region SQL 原型
var sqlBuilder = new StringBuilder(1280);
sqlBuilder.AppendLine("SELECT");
sqlBuilder.AppendLine(" msg.* ");
sqlBuilder.AppendLine("FROM");
sqlBuilder.AppendLine(" (");
sqlBuilder.AppendLine(" SELECT");
sqlBuilder.AppendLine(" um.Content,");
sqlBuilder.AppendLine(" um.CreationTime,");
sqlBuilder.AppendLine(" um.CreatorId,");
sqlBuilder.AppendLine(" um.SendUserName,");
sqlBuilder.AppendLine(" ac.NickName AS Object,");
sqlBuilder.AppendLine(" ac.AvatarUrl,");
sqlBuilder.AppendLine(" um.Source,");
sqlBuilder.AppendLine(" um.MessageId,");
sqlBuilder.AppendLine(" um.Type,");
sqlBuilder.AppendLine(" um.TenantId,");
sqlBuilder.AppendLine(" um.ReceiveUserId,");
sqlBuilder.AppendLine(" '' AS GroupId,");
sqlBuilder.AppendLine(" um.ExtraProperties");
sqlBuilder.AppendLine(" FROM");
sqlBuilder.AppendLine(" (");
sqlBuilder.AppendLine(" SELECT");
sqlBuilder.AppendLine(" um.* ");
sqlBuilder.AppendLine(" FROM");
sqlBuilder.AppendLine(" appusermessages um");
sqlBuilder.AppendLine(" INNER JOIN ( SELECT max( um.MessageId ) AS MessageId FROM appusermessages um");
sqlBuilder.AppendLine(" WHERE");
sqlBuilder.AppendLine(" um.ReceiveUserId = @ReceiveUserId");
if (state.HasValue)
{
sqlBuilder.AppendLine(" AND um.State = @State");
}
if (CurrentTenant.IsAvailable)
{
sqlBuilder.AppendLine(" AND um.TenantId = @TenantId");
}
sqlBuilder.AppendLine(" GROUP BY um.ReceiveUserId ) gum ON um.MessageId = gum.MessageId");
sqlBuilder.AppendLine(" ) um");
sqlBuilder.AppendLine(" LEFT JOIN appuserchatcards ac ON ac.UserId = um.CreatorId ");
sqlBuilder.AppendLine(" UNION ALL");
sqlBuilder.AppendLine(" SELECT");
sqlBuilder.AppendLine(" gm.Content,");
sqlBuilder.AppendLine(" gm.CreationTime,");
sqlBuilder.AppendLine(" gm.CreatorId,");
sqlBuilder.AppendLine(" gm.SendUserName,");
sqlBuilder.AppendLine(" ag.Name AS Object,");
sqlBuilder.AppendLine(" ag.AvatarUrl,");
sqlBuilder.AppendLine(" gm.Source,");
sqlBuilder.AppendLine(" gm.MessageId,");
sqlBuilder.AppendLine(" gm.Type,");
sqlBuilder.AppendLine(" gm.TenantId,");
sqlBuilder.AppendLine(" '' AS ReceiveUserId,");
sqlBuilder.AppendLine(" gm.GroupId,");
sqlBuilder.AppendLine(" gm.ExtraProperties");
sqlBuilder.AppendLine(" FROM");
sqlBuilder.AppendLine(" appgroupmessages gm");
sqlBuilder.AppendLine(" INNER JOIN (");
sqlBuilder.AppendLine(" SELECT");
sqlBuilder.AppendLine(" max( gm.MessageId ) AS MessageId ");
sqlBuilder.AppendLine(" FROM");
sqlBuilder.AppendLine(" appuserchatcards ac");
sqlBuilder.AppendLine(" LEFT JOIN appuserchatgroups acg ON acg.UserId = ac.UserId");
sqlBuilder.AppendLine(" LEFT JOIN appgroupmessages gm ON gm.GroupId = acg.GroupId ");
sqlBuilder.AppendLine(" WHERE");
sqlBuilder.AppendLine(" ac.UserId = @ReceiveUserId ");
if (state.HasValue)
{
sqlBuilder.AppendLine(" AND gm.State = @State");
}
if (CurrentTenant.IsAvailable)
{
sqlBuilder.AppendLine(" AND gm.TenantId = @TenantId");
}
sqlBuilder.AppendLine(" GROUP BY");
sqlBuilder.AppendLine(" gm.GroupId");
sqlBuilder.AppendLine(" ) ggm ON ggm.MessageId = gm.MessageId ");
sqlBuilder.AppendLine(" INNER JOIN appchatgroups ag on ag.GroupId = gm.GroupId");
sqlBuilder.AppendLine(" ) AS msg");
sqlBuilder.AppendLine("ORDER BY ");
sqlBuilder.AppendLine(" @Sorting");
sqlBuilder.AppendLine(" LIMIT @MaxResultCount");
using var dbContection = dbContext.Database.GetDbConnection();
await dbContection.OpenAsync();
using var command = dbContection.CreateCommand();
command.Transaction = dbContext.Database.CurrentTransaction?.GetDbTransaction();
command.CommandText = sqlBuilder.ToString();
var receivedUser = command.CreateParameter();
receivedUser.DbType = System.Data.DbType.Guid;
receivedUser.ParameterName = "@ReceiveUserId";
receivedUser.Value = userId;
command.Parameters.Add(receivedUser);
var sorttingParam = command.CreateParameter();
sorttingParam.DbType = System.Data.DbType.String;
sorttingParam.ParameterName = "@Sorting";
sorttingParam.Value = sorting;
command.Parameters.Add(sorttingParam);
var limitParam = command.CreateParameter();
limitParam.DbType = System.Data.DbType.Int32;
limitParam.ParameterName = "@MaxResultCount";
limitParam.Value = maxResultCount;
command.Parameters.Add(limitParam);
if (state.HasValue)
{
var stateParam = command.CreateParameter();
stateParam.DbType = System.Data.DbType.Int32;
stateParam.ParameterName = "@State";
stateParam.Value = (int)state.Value;
command.Parameters.Add(stateParam);
}
if (CurrentTenant.IsAvailable)
{
var tenantParam = command.CreateParameter();
tenantParam.DbType = System.Data.DbType.Guid;
tenantParam.ParameterName = "@TenantId";
tenantParam.Value = CurrentTenant.Id.Value;
command.Parameters.Add(tenantParam);
}
var messages = new List<LastChatMessage>();
using var reader = await command.ExecuteReaderAsync();
T GetValue<T>(DbDataReader reader, int index)
{
var value = reader.GetValue(index);
if (value == null || value == DBNull.Value)
{
return default;
}
var valueType = typeof(T);
var converter = TypeDescriptor.GetConverter(valueType);
if (converter.CanConvertFrom(value.GetType()))
{
return (T)converter.ConvertFrom(value);
}
return (T)Convert.ChangeType(value, typeof(T));
};
ExtraPropertyDictionary GetExtraProperties(DbDataReader reader, int index)
{
var value = reader.GetValue(index);
if (value == null || value == DBNull.Value)
{
return new ExtraPropertyDictionary();
}
var extraPropertiesAsJson = value.ToString();
if (extraPropertiesAsJson.IsNullOrEmpty() || extraPropertiesAsJson == "{}")
{
msg.Key.CreatorId,
msg.Key.ReceiveUserId,
MessageId = msg.Max(x => x.MessageId)
return new ExtraPropertyDictionary();
}
var deserializeOptions = new JsonSerializerOptions();
deserializeOptions.Converters.Add(new ObjectToInferredTypesConverter());
var dictionary = JsonSerializer.Deserialize<ExtraPropertyDictionary>(extraPropertiesAsJson, deserializeOptions) ??
new ExtraPropertyDictionary();
return dictionary;
}
while (reader.Read())
{
messages.Add(new LastChatMessage
{
Content = GetValue<string>(reader, 0),
SendTime = GetValue<DateTime>(reader, 1),
FormUserId = GetValue<Guid>(reader, 2),
FormUserName = GetValue<string>(reader, 3),
Object = GetValue<string>(reader, 4),
AvatarUrl = GetValue<string>(reader, 5),
Source = (MessageSourceTye)GetValue<int>(reader, 6),
MessageId = GetValue<string>(reader, 7),
MessageType = (MessageType)GetValue<int>(reader, 8),
TenantId = GetValue<Guid?>(reader, 9),
ToUserId = GetValue<string>(reader, 10),
GroupId = GetValue<string>(reader, 11),
ExtraProperties = GetExtraProperties(reader, 12),
});
}
return messages;
#endregion
#region 待 EF 团队解决此问题
//// 聚合用户消息
//var aggreUserMsgIdQuery = dbContext.Set<UserMessage>()
// .Where(msg => msg.ReceiveUserId == userId)
// .WhereIf(state.HasValue, x => x.SendState == state)
// .GroupBy(msg => msg.ReceiveUserId)
// .Select(msg => new
// {
// MessageId = msg.Max(x => x.MessageId)
// });
//var joinUserMsg = from um in dbContext.Set<UserMessage>()
// join aum in aggreUserMsgIdQuery
// on um.MessageId equals aum.MessageId
// join ucc in dbContext.Set<UserChatCard>()
// on um.CreatorId equals ucc.UserId
// select new LastChatMessage
// {
// Content = um.Content,
// SendTime = um.CreationTime,
// FormUserId = um.CreatorId.Value,
// FormUserName = um.SendUserName,
// Object = ucc.NickName,
// AvatarUrl = ucc.AvatarUrl,
// Source = um.Source,
// MessageId = Convert.ToString(um.MessageId),
// MessageType = um.Type,
// TenantId = um.TenantId,
// // ToUserId = Convert.ToString(um.ReceiveUserId),
// // GroupId = "",
// };
//// 聚合群组消息
//var aggreGroupMsgIdQuery = from ucc in dbContext.Set<UserChatCard>()
// join ucg in dbContext.Set<UserChatGroup>()
// on ucc.UserId equals ucg.UserId
// join gm in dbContext.Set<GroupMessage>()
// on ucg.GroupId equals gm.GroupId
// where ucc.UserId.Equals(userId)
// group gm by gm.GroupId into ggm
// select new
// {
// MessageId = ggm.Max(gm => gm.MessageId),
// };
//var joinGroupMsg = from gm in dbContext.Set<GroupMessage>()
// join agm in aggreGroupMsgIdQuery
// on gm.MessageId equals agm.MessageId
// join cg in dbContext.Set<ChatGroup>()
// on gm.GroupId equals cg.GroupId
// select new LastChatMessage
// {
// Content = gm.Content,
// SendTime = gm.CreationTime,
// FormUserId = gm.CreatorId.Value,
// FormUserName = gm.SendUserName,
// Object = cg.Name,
// AvatarUrl = cg.AvatarUrl,
// Source = gm.Source,
// MessageId = Convert.ToString(gm.MessageId),
// MessageType = gm.Type,
// TenantId = gm.TenantId,
// // ToUserId = "",
// // GroupId = Convert.ToString(gm.GroupId)
// };
//return await joinUserMsg
// .Concat(joinGroupMsg)
// .OrderBy(sorting)
// .Take(maxResultCount)
// .ToListAsync(GetCancellationToken(cancellationToken));
#endregion
var userMessageQuery = from msg in dbContext.Set<UserMessage>()
join gMsg in groupMsgQuery
on msg.MessageId equals gMsg.MessageId
select new LastChatMessage
{
Content = msg.Content,
SendTime = msg.CreationTime,
FormUserId = msg.CreatorId.Value,
FormUserName = msg.SendUserName,
MessageId = msg.MessageId.ToString(),
MessageType = msg.Type,
TenantId = msg.TenantId,
ToUserId = msg.ReceiveUserId
};
return await userMessageQuery
.OrderBy(sorting ?? nameof(LastChatMessage.SendTime))
.Take(maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<List<UserMessage>> GetUserMessagesAsync(
@ -199,7 +442,8 @@ namespace LINGYUN.Abp.MessageService.Chat
var userMessages = await (await GetDbContextAsync()).Set<UserMessage>()
.Where(x => (x.CreatorId.Equals(sendUserId) && x.ReceiveUserId.Equals(receiveUserId)) ||
x.CreatorId.Equals(receiveUserId) && x.ReceiveUserId.Equals(sendUserId))
.WhereIf(type != null, x => x.Type.Equals(type))
.WhereIf(type.HasValue, x => x.Type.Equals(type))
.Where(x => x.State == MessageState.Send || x.State == MessageState.Read)
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.OrderBy(sorting ?? nameof(UserMessage.MessageId))
.PageBy(skipCount, maxResultCount)
@ -219,7 +463,8 @@ namespace LINGYUN.Abp.MessageService.Chat
var userMessagesCount = await (await GetDbContextAsync()).Set<UserMessage>()
.Where(x => (x.CreatorId.Equals(sendUserId) && x.ReceiveUserId.Equals(receiveUserId)) ||
x.CreatorId.Equals(receiveUserId) && x.ReceiveUserId.Equals(sendUserId))
.WhereIf(type != null, x => x.Type.Equals(type))
.WhereIf(type.HasValue, x => x.Type.Equals(type))
.Where(x => x.State == MessageState.Send || x.State == MessageState.Read)
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter))
.LongCountAsync(GetCancellationToken(cancellationToken));

2
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs

@ -27,7 +27,7 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore
b.Property(p => p.NotificationName).HasMaxLength(NotificationConsts.MaxNameLength).IsRequired();
b.Property(p => p.NotificationTypeName).HasMaxLength(NotificationConsts.MaxTypeNameLength).IsRequired();
b.Property(p => p.NotificationData).HasMaxLength(NotificationConsts.MaxDataLength).IsRequired();
//b.Property(p => p.NotificationData).HasMaxLength(NotificationConsts.MaxDataLength).IsRequired();
b.ConfigureByConvention();

11
aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs

@ -17,13 +17,13 @@ namespace LINGYUN.Abp.MessageService.Notifications
IUserNotificationRepository, ITransientDependency
{
public EfCoreUserNotificationRepository(
IDbContextProvider<IMessageServiceDbContext> dbContextProvider)
IDbContextProvider<IMessageServiceDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<bool> AnyAsync(
Guid userId,
Guid userId,
long notificationId,
CancellationToken cancellationToken = default)
{
@ -75,7 +75,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
public virtual async Task<int> GetCountAsync(
Guid userId,
Guid userId,
string filter = "",
NotificationReadState? readState = null,
CancellationToken cancellationToken = default)
@ -98,7 +98,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
}
public virtual async Task<List<Notification>> GetListAsync(
Guid userId,
Guid userId,
string filter = "",
string sorting = nameof(Notification.CreationTime),
NotificationReadState? readState = null,
@ -106,6 +106,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{
sorting ??= $"{nameof(Notification.CreationTime)} DESC";
var dbContext = await GetDbContextAsync();
var userNotifilerQuery = dbContext.Set<UserNotification>()
.Where(x => x.UserId == userId)
@ -120,7 +121,7 @@ namespace LINGYUN.Abp.MessageService.Notifications
.WhereIf(!filter.IsNullOrWhiteSpace(), nf =>
nf.NotificationName.Contains(filter) ||
nf.NotificationTypeName.Contains(filter))
.OrderBy(sorting ??= nameof(Notification.CreationTime))
.OrderBy(sorting)
.PageBy(skipCount, maxResultCount)
.AsNoTracking()
.ToListAsync(GetCancellationToken(cancellationToken));

6
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs

@ -72,13 +72,13 @@ namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
await SubscribeMessager
.SendAsync(
identifier.UserId, templateId, redirect, weAppLang,
weAppState, notification.Data.Properties, cancellationToken);
weAppState, notification.Data.ExtraProperties, cancellationToken);
}
else
{
var weChatWeAppNotificationData = new SubscribeMessage(templateId, redirect, weAppState, weAppLang);
// 写入模板数据
weChatWeAppNotificationData.WriteData(notification.Data.Properties);
weChatWeAppNotificationData.WriteData(notification.Data.ExtraProperties);
Logger.LogDebug($"Sending wechat weapp notification: {notification.Name}");
@ -94,7 +94,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
protected string GetOrDefault(NotificationData data, string key, string defaultValue)
{
if (data.Properties.TryGetValue(key, out object value))
if (data.ExtraProperties.TryGetValue(key, out object value))
{
// 取得了数据就删除对应键值
// data.Properties.Remove(key);

5
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs

@ -109,15 +109,12 @@ namespace LINGYUN.Abp.MessageService
app.UseRouting();
// 跨域
app.UseCors(DefaultCorsPolicyName);
// 加入自定义中间件
app.UseSignalRJwtToken();
// TODO: 还有没有其他方法在iframe中传递身份令牌?
app.UseHangfireAuthorication();
// 认证
app.UseAuthentication();
app.UseAbpClaimsMap();
// jwt
app.UseJwtTokenMiddleware();
// 授权
app.UseAuthorization();
// 多租户
app.UseMultiTenancy();

3
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantSynchronizer.cs

@ -3,6 +3,7 @@ using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MultiTenancy;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.RealTime.Localization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
@ -62,7 +63,7 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
await SendNotificationAsync(eventData);
await unitOfWork.SaveChangesAsync();
await unitOfWork.CompleteAsync();
}
}
}

116
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Local/UserCreateJoinIMEventHandler.cs

@ -1,57 +1,59 @@
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
public class UserCreateJoinIMEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency
{
private readonly IChatDataSeeder _chatDataSeeder;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public UserCreateJoinIMEventHandler(
IChatDataSeeder chatDataSeeder,
INotificationSubscriptionManager notificationSubscriptionManager)
{
_chatDataSeeder = chatDataSeeder;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
/// <summary>
/// 接收添加用户事件,初始化IM用户种子
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
[UnitOfWork]
public virtual async Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData)
{
await SeedChatDataAsync(eventData.Entity);
}
protected virtual async Task SeedChatDataAsync(IUserData user)
{
await _chatDataSeeder.SeedAsync(user);
}
protected virtual async Task SeedUserSubscriptionNotifiersAsync(IUserData user)
{
var userIdentifier = new UserIdentifier(user.Id, user.UserName);
await _notificationSubscriptionManager
.SubscribeAsync(
user.TenantId,
userIdentifier,
MessageServiceNotificationNames.IM.FriendValidation);
await _notificationSubscriptionManager
.SubscribeAsync(
user.TenantId,
userIdentifier,
MessageServiceNotificationNames.IM.NewFriend);
}
}
}
using LINGYUN.Abp.MessageService.Chat;
using LINGYUN.Abp.MessageService.Notifications;
using LINGYUN.Abp.Notifications;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
public class UserCreateJoinIMEventHandler : ILocalEventHandler<EntityCreatedEventData<UserEto>>, ITransientDependency
{
private readonly IChatDataSeeder _chatDataSeeder;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
public UserCreateJoinIMEventHandler(
IChatDataSeeder chatDataSeeder,
INotificationSubscriptionManager notificationSubscriptionManager)
{
_chatDataSeeder = chatDataSeeder;
_notificationSubscriptionManager = notificationSubscriptionManager;
}
/// <summary>
/// 接收添加用户事件,初始化IM用户种子
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
[UnitOfWork]
public virtual async Task HandleEventAsync(EntityCreatedEventData<UserEto> eventData)
{
await SeedChatDataAsync(eventData.Entity);
await SeedUserSubscriptionNotifiersAsync(eventData.Entity);
}
protected virtual async Task SeedChatDataAsync(IUserData user)
{
await _chatDataSeeder.SeedAsync(user);
}
protected virtual async Task SeedUserSubscriptionNotifiersAsync(IUserData user)
{
var userIdentifier = new UserIdentifier(user.Id, user.UserName);
await _notificationSubscriptionManager
.SubscribeAsync(
user.TenantId,
userIdentifier,
MessageServiceNotificationNames.IM.FriendValidation);
await _notificationSubscriptionManager
.SubscribeAsync(
user.TenantId,
userIdentifier,
MessageServiceNotificationNames.IM.NewFriend);
}
}
}

1
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs

@ -1,5 +1,6 @@
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.RealTime.Localization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

621
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111014501_Add-Base-Type-ExtraProp-To-Notification.Designer.cs

@ -0,0 +1,621 @@
// <auto-generated />
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("20211111014501_Add-Base-Type-ExtraProp-To-Notification")]
partial class AddBaseTypeExtraPropToNotification
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.12");
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<string>("AvatarUrl")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<DateTime?>("Birthday")
.HasColumnType("datetime(6)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("LastOnlineTime")
.HasColumnType("datetime(6)");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<int>("Sex")
.HasColumnType("int");
b.Property<string>("Sign")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("State")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Black")
.HasColumnType("tinyint(1)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<bool>("DontDisturb")
.HasColumnType("tinyint(1)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<Guid>("FrientId")
.HasColumnType("char(36)");
b.Property<string>("RemarkName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("SpecialFocus")
.HasColumnType("tinyint(1)");
b.Property<byte>("Status")
.HasColumnType("tinyint unsigned");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "FrientId");
b.ToTable("AppUserChatFriends");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.ChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<Guid>("AdminUserId")
.HasColumnType("char(36)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<string>("AvatarUrl")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.Property<string>("Notice")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Tag")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AppChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId", "UserId");
b.ToTable("AppUserChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserGroupCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<DateTime?>("SilenceEnd")
.HasColumnType("datetime(6)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserGroupCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("NotificationTypeName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<sbyte>("Severity")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "NotificationName");
b.ToTable("AppNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<int>("ReadStatus")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationId")
.HasDatabaseName("IX_Tenant_User_Notification_Id");
b.ToTable("AppUserNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasDefaultValue("/");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationName")
.IsUnique()
.HasDatabaseName("IX_Tenant_User_Notification_Name");
b.ToTable("AppUserSubscribes");
});
#pragma warning restore 612, 618
}
}
}

36
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111014501_Add-Base-Type-ExtraProp-To-Notification.cs

@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace LINGYUN.Abp.MessageService.Migrations
{
public partial class AddBaseTypeExtraPropToNotification : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "NotificationData",
table: "AppNotifications");
migrationBuilder.AddColumn<string>(
name: "ExtraProperties",
table: "AppNotifications",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ExtraProperties",
table: "AppNotifications");
migrationBuilder.AddColumn<string>(
name: "NotificationData",
table: "AppNotifications",
type: "longtext",
maxLength: 1048576,
nullable: false)
.Annotation("MySql:CharSet", "utf8mb4");
}
}
}

627
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111080938_Add-Source-Type-To-Chat-Message.Designer.cs

@ -0,0 +1,627 @@
// <auto-generated />
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("20211111080938_Add-Source-Type-To-Chat-Message")]
partial class AddSourceTypeToChatMessage
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.12");
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<string>("AvatarUrl")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<DateTime?>("Birthday")
.HasColumnType("datetime(6)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("LastOnlineTime")
.HasColumnType("datetime(6)");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<int>("Sex")
.HasColumnType("int");
b.Property<string>("Sign")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("State")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Black")
.HasColumnType("tinyint(1)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<bool>("DontDisturb")
.HasColumnType("tinyint(1)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<Guid>("FrientId")
.HasColumnType("char(36)");
b.Property<string>("RemarkName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("SpecialFocus")
.HasColumnType("tinyint(1)");
b.Property<byte>("Status")
.HasColumnType("tinyint unsigned");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "FrientId");
b.ToTable("AppUserChatFriends");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("Source")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.ChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<Guid>("AdminUserId")
.HasColumnType("char(36)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<string>("AvatarUrl")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.Property<string>("Notice")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Tag")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AppChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("Source")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId", "UserId");
b.ToTable("AppUserChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserGroupCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<DateTime?>("SilenceEnd")
.HasColumnType("datetime(6)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserGroupCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("NotificationTypeName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<sbyte>("Severity")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "NotificationName");
b.ToTable("AppNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<int>("ReadStatus")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationId")
.HasDatabaseName("IX_Tenant_User_Notification_Id");
b.ToTable("AppUserNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasDefaultValue("/");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationName")
.IsUnique()
.HasDatabaseName("IX_Tenant_User_Notification_Name");
b.ToTable("AppUserSubscribes");
});
#pragma warning restore 612, 618
}
}
}

35
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111080938_Add-Source-Type-To-Chat-Message.cs

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace LINGYUN.Abp.MessageService.Migrations
{
public partial class AddSourceTypeToChatMessage : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Source",
table: "AppUserMessages",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "Source",
table: "AppGroupMessages",
type: "int",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Source",
table: "AppUserMessages");
migrationBuilder.DropColumn(
name: "Source",
table: "AppGroupMessages");
}
}
}

630
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111221335_Add-Field-Static-To-Chat-Friend.Designer.cs

@ -0,0 +1,630 @@
// <auto-generated />
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("20211111221335_Add-Field-Static-To-Chat-Friend")]
partial class AddFieldStaticToChatFriend
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.12");
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<string>("AvatarUrl")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<DateTime?>("Birthday")
.HasColumnType("datetime(6)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("LastOnlineTime")
.HasColumnType("datetime(6)");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<int>("Sex")
.HasColumnType("int");
b.Property<string>("Sign")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("State")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Black")
.HasColumnType("tinyint(1)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<bool>("DontDisturb")
.HasColumnType("tinyint(1)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<Guid>("FrientId")
.HasColumnType("char(36)");
b.Property<bool>("IsStatic")
.HasColumnType("tinyint(1)");
b.Property<string>("RemarkName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("SpecialFocus")
.HasColumnType("tinyint(1)");
b.Property<byte>("Status")
.HasColumnType("tinyint unsigned");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "FrientId");
b.ToTable("AppUserChatFriends");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("Source")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.ChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<Guid>("AdminUserId")
.HasColumnType("char(36)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<string>("AvatarUrl")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.Property<string>("Notice")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Tag")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AppChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<sbyte>("SendState")
.HasColumnType("tinyint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("Source")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId", "UserId");
b.ToTable("AppUserChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserGroupCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<DateTime?>("SilenceEnd")
.HasColumnType("datetime(6)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserGroupCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("NotificationTypeName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<sbyte>("Severity")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "NotificationName");
b.ToTable("AppNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<int>("ReadStatus")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationId")
.HasDatabaseName("IX_Tenant_User_Notification_Id");
b.ToTable("AppUserNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasDefaultValue("/");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationName")
.IsUnique()
.HasDatabaseName("IX_Tenant_User_Notification_Name");
b.ToTable("AppUserSubscribes");
});
#pragma warning restore 612, 618
}
}
}

24
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211111221335_Add-Field-Static-To-Chat-Friend.cs

@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace LINGYUN.Abp.MessageService.Migrations
{
public partial class AddFieldStaticToChatFriend : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsStatic",
table: "AppUserChatFriends",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsStatic",
table: "AppUserChatFriends");
}
}
}

630
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211112083050_Rename-Field-SendState-To-State.Designer.cs

@ -0,0 +1,630 @@
// <auto-generated />
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("20211112083050_Rename-Field-SendState-To-State")]
partial class RenameFieldSendStateToState
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.12");
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<string>("AvatarUrl")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<DateTime?>("Birthday")
.HasColumnType("datetime(6)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("LastOnlineTime")
.HasColumnType("datetime(6)");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<int>("Sex")
.HasColumnType("int");
b.Property<string>("Sign")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("State")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Black")
.HasColumnType("tinyint(1)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<bool>("DontDisturb")
.HasColumnType("tinyint(1)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<Guid>("FrientId")
.HasColumnType("char(36)");
b.Property<bool>("IsStatic")
.HasColumnType("tinyint(1)");
b.Property<string>("RemarkName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("SpecialFocus")
.HasColumnType("tinyint(1)");
b.Property<byte>("Status")
.HasColumnType("tinyint unsigned");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "FrientId");
b.ToTable("AppUserChatFriends");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("AllowAddFriend")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowReceiveMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<bool>("RequireAddFriendValition")
.HasColumnType("tinyint(1)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserChatSettings");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<Guid>("ReceiveUserId")
.HasColumnType("char(36)");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("Source")
.HasColumnType("int");
b.Property<sbyte>("State")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "ReceiveUserId");
b.ToTable("AppUserMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.ChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Address")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<Guid>("AdminUserId")
.HasColumnType("char(36)");
b.Property<bool>("AllowAnonymous")
.HasColumnType("tinyint(1)");
b.Property<bool>("AllowSendMessage")
.HasColumnType("tinyint(1)");
b.Property<string>("AvatarUrl")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("MaxUserCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.Property<string>("Notice")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Tag")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name");
b.ToTable("AppChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupChatBlack", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid>("ShieldUserId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupChatBlacks");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.GroupMessage", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(1048576)
.HasColumnType("longtext");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<long>("MessageId")
.HasColumnType("bigint");
b.Property<string>("SendUserName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("Source")
.HasColumnType("int");
b.Property<sbyte>("State")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId");
b.ToTable("AppGroupMessages");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserChatGroup", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<long>("GroupId")
.HasColumnType("bigint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "GroupId", "UserId");
b.ToTable("AppUserChatGroups");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Groups.UserGroupCard", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAdmin")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("NickName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<DateTime?>("SilenceEnd")
.HasColumnType("datetime(6)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId");
b.ToTable("AppUserGroupCards");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<DateTime?>("ExpirationTime")
.HasColumnType("datetime(6)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("NotificationTypeName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<sbyte>("Severity")
.HasColumnType("tinyint");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("TenantId", "NotificationName");
b.ToTable("AppNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<long>("NotificationId")
.HasColumnType("bigint");
b.Property<int>("ReadStatus")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationId")
.HasDatabaseName("IX_Tenant_User_Notification_Id");
b.ToTable("AppUserNotifications");
});
modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<string>("NotificationName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasDefaultValue("/");
b.HasKey("Id");
b.HasIndex("TenantId", "UserId", "NotificationName")
.IsUnique()
.HasDatabaseName("IX_Tenant_User_Notification_Name");
b.ToTable("AppUserSubscribes");
});
#pragma warning restore 612, 618
}
}
}

33
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20211112083050_Rename-Field-SendState-To-State.cs

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace LINGYUN.Abp.MessageService.Migrations
{
public partial class RenameFieldSendStateToState : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "SendState",
table: "AppUserMessages",
newName: "State");
migrationBuilder.RenameColumn(
name: "SendState",
table: "AppGroupMessages",
newName: "State");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "State",
table: "AppUserMessages",
newName: "SendState");
migrationBuilder.RenameColumn(
name: "State",
table: "AppGroupMessages",
newName: "SendState");
}
}
}

866
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs

File diff suppressed because it is too large

164
aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/SmsNotificationDataMapping_Tests.cs

@ -1,82 +1,82 @@
using Microsoft.Extensions.Options;
using Shouldly;
using System;
using Xunit;
namespace LINGYUN.Abp.Notifications.Sms
{
public class SmsNotificationDataMapping_Tests : AbpNotificationsSmsTestsBase
{
private readonly NotificationData _notificationData;
protected AbpNotificationOptions NotificationOptions { get; }
protected AbpNotificationsSmsOptions NotificationSmsOptions { get; }
public SmsNotificationDataMapping_Tests()
{
NotificationOptions = GetRequiredService<IOptions<AbpNotificationOptions>>().Value;
NotificationSmsOptions = GetRequiredService<IOptions<AbpNotificationsSmsOptions>>().Value;
_notificationData = new NotificationData();
InitNotificationData(_notificationData);
}
private void InitNotificationData(NotificationData data)
{
data.WriteStandardData("title", "message", DateTime.Now, "formUser", "description");
data.WriteStandardData(NotificationSmsOptions.TemplateParamsPrefix, "phoneNumber", "13800138000");
data.WriteStandardData(NotificationSmsOptions.TemplateParamsPrefix, "template", "SM_202011250901");
data.TrySetData("otherDataKey", "otherDataValue");
}
[Fact]
public void Mapping_Sms_Notification_Data_Test()
{
var mappingSmsItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test1);
mappingSmsItem.ShouldNotBeNull();
var mappingSmsData = mappingSmsItem.MappingFunc(_notificationData);
mappingSmsData.TryGetData("phoneNumber").ShouldNotBeNull();
mappingSmsData.TryGetData("phoneNumber").ToString().ShouldBe("13800138000");
mappingSmsData.TryGetData("template").ShouldNotBeNull();
mappingSmsData.TryGetData("template").ToString().ShouldBe("SM_202011250901");
// 按照预定义规则,这条数据被丢弃
mappingSmsData.TryGetData("otherDataKey").ShouldBeNull();
}
[Fact]
public void Mapping_Standard_Notification_Data_Test()
{
var mappingStandardItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test2);
var mappingStandardData = mappingStandardItem.MappingFunc(_notificationData);
// 按照自定义规则,其他数据被丢弃
mappingStandardData.TryGetData("phoneNumber").ShouldBeNull();
mappingStandardData.TryGetData("template").ShouldBeNull();
mappingStandardData.TryGetData("otherDataKey").ShouldBeNull();
mappingStandardData.Properties.Count.ShouldBe(6);
}
[Fact]
public void Mapping_Origin_Notification_Data_Test()
{
var mappingOriginItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test3);
var mappingOriginData = mappingOriginItem.MappingFunc(_notificationData);
// 按照自定义规则,所有数据被保留
mappingOriginData.TryGetData(NotificationSmsOptions.TemplateParamsPrefix + "phoneNumber").ShouldNotBeNull();
mappingOriginData.TryGetData(NotificationSmsOptions.TemplateParamsPrefix + "template").ShouldNotBeNull();
mappingOriginData.TryGetData("otherDataKey").ShouldNotBeNull();
mappingOriginData.Properties.Count.ShouldBe(9);
}
}
}
using Microsoft.Extensions.Options;
using Shouldly;
using System;
using Xunit;
namespace LINGYUN.Abp.Notifications.Sms
{
public class SmsNotificationDataMapping_Tests : AbpNotificationsSmsTestsBase
{
private readonly NotificationData _notificationData;
protected AbpNotificationOptions NotificationOptions { get; }
protected AbpNotificationsSmsOptions NotificationSmsOptions { get; }
public SmsNotificationDataMapping_Tests()
{
NotificationOptions = GetRequiredService<IOptions<AbpNotificationOptions>>().Value;
NotificationSmsOptions = GetRequiredService<IOptions<AbpNotificationsSmsOptions>>().Value;
_notificationData = new NotificationData();
InitNotificationData(_notificationData);
}
private void InitNotificationData(NotificationData data)
{
data.WriteStandardData("title", "message", DateTime.Now, "formUser", "description");
data.WriteStandardData(NotificationSmsOptions.TemplateParamsPrefix, "phoneNumber", "13800138000");
data.WriteStandardData(NotificationSmsOptions.TemplateParamsPrefix, "template", "SM_202011250901");
data.TrySetData("otherDataKey", "otherDataValue");
}
[Fact]
public void Mapping_Sms_Notification_Data_Test()
{
var mappingSmsItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test1);
mappingSmsItem.ShouldNotBeNull();
var mappingSmsData = mappingSmsItem.MappingFunc(_notificationData);
mappingSmsData.TryGetData("phoneNumber").ShouldNotBeNull();
mappingSmsData.TryGetData("phoneNumber").ToString().ShouldBe("13800138000");
mappingSmsData.TryGetData("template").ShouldNotBeNull();
mappingSmsData.TryGetData("template").ToString().ShouldBe("SM_202011250901");
// 按照预定义规则,这条数据被丢弃
mappingSmsData.TryGetData("otherDataKey").ShouldBeNull();
}
[Fact]
public void Mapping_Standard_Notification_Data_Test()
{
var mappingStandardItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test2);
var mappingStandardData = mappingStandardItem.MappingFunc(_notificationData);
// 按照自定义规则,其他数据被丢弃
mappingStandardData.TryGetData("phoneNumber").ShouldBeNull();
mappingStandardData.TryGetData("template").ShouldBeNull();
mappingStandardData.TryGetData("otherDataKey").ShouldBeNull();
mappingStandardData.ExtraProperties.Count.ShouldBe(6);
}
[Fact]
public void Mapping_Origin_Notification_Data_Test()
{
var mappingOriginItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test3);
var mappingOriginData = mappingOriginItem.MappingFunc(_notificationData);
// 按照自定义规则,所有数据被保留
mappingOriginData.TryGetData(NotificationSmsOptions.TemplateParamsPrefix + "phoneNumber").ShouldNotBeNull();
mappingOriginData.TryGetData(NotificationSmsOptions.TemplateParamsPrefix + "template").ShouldNotBeNull();
mappingOriginData.TryGetData("otherDataKey").ShouldNotBeNull();
mappingOriginData.ExtraProperties.Count.ShouldBe(9);
}
}
}

154
aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/WeChatMiniProgramNotificationDataMapping_Tests.cs

@ -1,77 +1,77 @@
using Microsoft.Extensions.Options;
using Shouldly;
using System;
using Xunit;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
public class WeChatMiniProgramNotificationDataMapping_Tests : AbpNotificationsWeChatMiniProgramTestsBase
{
private readonly NotificationData _notificationData;
protected AbpNotificationOptions NotificationOptions { get; }
protected AbpNotificationsWeChatMiniProgramOptions NotificationWeChatMiniProgramOptions { get; }
public WeChatMiniProgramNotificationDataMapping_Tests()
{
NotificationOptions = GetRequiredService<IOptions<AbpNotificationOptions>>().Value;
NotificationWeChatMiniProgramOptions = GetRequiredService<IOptions<AbpNotificationsWeChatMiniProgramOptions>>().Value;
_notificationData = new NotificationData();
InitNotificationData(_notificationData);
}
private void InitNotificationData(NotificationData data)
{
data.WriteStandardData("title", "message", DateTime.Now, "formUser", "description");
data.WriteStandardData(NotificationWeChatMiniProgramOptions.DefaultMsgPrefix, "openid", "TEST");
data.TrySetData("otherDataKey", "otherDataValue");
}
[Fact]
public void Mapping_WeChatMiniProgram_Notification_Data_Test()
{
var mappingOpenIdItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test1);
mappingOpenIdItem.ShouldNotBeNull();
var mappingOpenIdData = mappingOpenIdItem.MappingFunc(_notificationData);
mappingOpenIdData.TryGetData("openid").ShouldNotBeNull();
mappingOpenIdData.TryGetData("openid").ToString().ShouldBe("TEST");
// 按照预定义规则,这条数据被丢弃
mappingOpenIdData.TryGetData("otherDataKey").ShouldBeNull();
}
[Fact]
public void Mapping_Standard_Notification_Data_Test()
{
var mappingStandardItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test2);
var mappingStandardData = mappingStandardItem.MappingFunc(_notificationData);
// 按照自定义规则,其他数据被丢弃
mappingStandardData.TryGetData("openid").ShouldBeNull();
mappingStandardData.TryGetData("otherDataKey").ShouldBeNull();
mappingStandardData.Properties.Count.ShouldBe(6);
}
[Fact]
public void Mapping_Origin_Notification_Data_Test()
{
var mappingOriginItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test3);
var mappingOriginData = mappingOriginItem.MappingFunc(_notificationData);
// 按照自定义规则,所有数据被保留
mappingOriginData.TryGetData(NotificationWeChatMiniProgramOptions.DefaultMsgPrefix + "openid").ShouldNotBeNull();
mappingOriginData.TryGetData("otherDataKey").ShouldNotBeNull();
mappingOriginData.Properties.Count.ShouldBe(8);
}
}
}
using Microsoft.Extensions.Options;
using Shouldly;
using System;
using Xunit;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
public class WeChatMiniProgramNotificationDataMapping_Tests : AbpNotificationsWeChatMiniProgramTestsBase
{
private readonly NotificationData _notificationData;
protected AbpNotificationOptions NotificationOptions { get; }
protected AbpNotificationsWeChatMiniProgramOptions NotificationWeChatMiniProgramOptions { get; }
public WeChatMiniProgramNotificationDataMapping_Tests()
{
NotificationOptions = GetRequiredService<IOptions<AbpNotificationOptions>>().Value;
NotificationWeChatMiniProgramOptions = GetRequiredService<IOptions<AbpNotificationsWeChatMiniProgramOptions>>().Value;
_notificationData = new NotificationData();
InitNotificationData(_notificationData);
}
private void InitNotificationData(NotificationData data)
{
data.WriteStandardData("title", "message", DateTime.Now, "formUser", "description");
data.WriteStandardData(NotificationWeChatMiniProgramOptions.DefaultMsgPrefix, "openid", "TEST");
data.TrySetData("otherDataKey", "otherDataValue");
}
[Fact]
public void Mapping_WeChatMiniProgram_Notification_Data_Test()
{
var mappingOpenIdItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test1);
mappingOpenIdItem.ShouldNotBeNull();
var mappingOpenIdData = mappingOpenIdItem.MappingFunc(_notificationData);
mappingOpenIdData.TryGetData("openid").ShouldNotBeNull();
mappingOpenIdData.TryGetData("openid").ToString().ShouldBe("TEST");
// 按照预定义规则,这条数据被丢弃
mappingOpenIdData.TryGetData("otherDataKey").ShouldBeNull();
}
[Fact]
public void Mapping_Standard_Notification_Data_Test()
{
var mappingStandardItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test2);
var mappingStandardData = mappingStandardItem.MappingFunc(_notificationData);
// 按照自定义规则,其他数据被丢弃
mappingStandardData.TryGetData("openid").ShouldBeNull();
mappingStandardData.TryGetData("otherDataKey").ShouldBeNull();
mappingStandardData.ExtraProperties.Count.ShouldBe(6);
}
[Fact]
public void Mapping_Origin_Notification_Data_Test()
{
var mappingOriginItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test3);
var mappingOriginData = mappingOriginItem.MappingFunc(_notificationData);
// 按照自定义规则,所有数据被保留
mappingOriginData.TryGetData(NotificationWeChatMiniProgramOptions.DefaultMsgPrefix + "openid").ShouldNotBeNull();
mappingOriginData.TryGetData("otherDataKey").ShouldNotBeNull();
mappingOriginData.ExtraProperties.Count.ShouldBe(8);
}
}
}

Loading…
Cancel
Save