diff --git a/aspnet-core/LINGYUN.MicroService.sln b/aspnet-core/LINGYUN.MicroService.sln index e01605823..358dab774 100644 --- a/aspnet-core/LINGYUN.MicroService.sln +++ b/aspnet-core/LINGYUN.MicroService.sln @@ -251,6 +251,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManag EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Web", "modules\account\LINGYUN.Abp.Account.Web\LINGYUN.Abp.Account.Web.csproj", "{5F43141B-6C63-4547-B9D6-D69EC3D7CA7E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AspNetCore.SignalR.JwtToken", "modules\common\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj", "{A66D48C9-F141-4111-9169-CEB64AFFF61D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -665,6 +667,10 @@ Global {5F43141B-6C63-4547-B9D6-D69EC3D7CA7E}.Debug|Any CPU.Build.0 = Debug|Any CPU {5F43141B-6C63-4547-B9D6-D69EC3D7CA7E}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F43141B-6C63-4547-B9D6-D69EC3D7CA7E}.Release|Any CPU.Build.0 = Release|Any CPU + {A66D48C9-F141-4111-9169-CEB64AFFF61D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A66D48C9-F141-4111-9169-CEB64AFFF61D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A66D48C9-F141-4111-9169-CEB64AFFF61D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A66D48C9-F141-4111-9169-CEB64AFFF61D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -791,6 +797,7 @@ Global {B46D6DAF-98C6-441F-9FA5-3CAD7CF27727} = {CC362C67-6FC1-42B3-A130-8120AA8D790C} {2D377D3A-70EC-4BB3-9F4C-6C933693DA98} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {5F43141B-6C63-4547-B9D6-D69EC3D7CA7E} = {9E72FEB9-A626-4312-892B-CDD043879758} + {A66D48C9-F141-4111-9169-CEB64AFFF61D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj new file mode 100644 index 000000000..5e09bfd3b --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj @@ -0,0 +1,14 @@ + + + + + + netcoreapp3.1 + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN/Abp/AspNetCore/SignalR/JwtToken/AbpAspNetCoreSignalRJwtTokenMapPathOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN/Abp/AspNetCore/SignalR/JwtToken/AbpAspNetCoreSignalRJwtTokenMapPathOptions.cs new file mode 100644 index 000000000..76c4ec29d --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN/Abp/AspNetCore/SignalR/JwtToken/AbpAspNetCoreSignalRJwtTokenMapPathOptions.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.AspNetCore.SignalR.JwtToken +{ + public class AbpAspNetCoreSignalRJwtTokenMapPathOptions + { + public List MapJwtTokenPaths { get; set; } + public AbpAspNetCoreSignalRJwtTokenMapPathOptions() + { + MapJwtTokenPaths = new List(); + } + + public void MapPath(string path) + { + if (path.StartsWith("/signalr-hubs/")) + { + MapJwtTokenPaths.AddIfNotContains(path); + } + else + { + MapJwtTokenPaths.AddIfNotContains($"/signalr-hubs/{path}"); + } + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN/Abp/AspNetCore/SignalR/JwtToken/AbpAspNetCoreSignalRJwtTokenModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN/Abp/AspNetCore/SignalR/JwtToken/AbpAspNetCoreSignalRJwtTokenModule.cs new file mode 100644 index 000000000..bb478ed30 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/LINGYUN/Abp/AspNetCore/SignalR/JwtToken/AbpAspNetCoreSignalRJwtTokenModule.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.SignalR; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.AspNetCore.SignalR.JwtToken +{ + [DependsOn( + typeof(AbpAspNetCoreSignalRModule))] + public class AbpAspNetCoreSignalRJwtTokenModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + + Configure(configuration.GetSection("SignalR:MapPath")); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenApplicationBuilderExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenApplicationBuilderExtensions.cs similarity index 100% rename from aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenApplicationBuilderExtensions.cs rename to aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/Microsoft/AspNetCore/Builder/SignalRJwtTokenApplicationBuilderExtensions.cs diff --git a/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/Microsoft/AspNetCore/Http/SignalRJwtTokenMiddleware.cs b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/Microsoft/AspNetCore/Http/SignalRJwtTokenMiddleware.cs new file mode 100644 index 000000000..8944ed0e0 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR/Microsoft/AspNetCore/Http/SignalRJwtTokenMiddleware.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.AspNetCore.SignalR.JwtToken; +using Microsoft.Extensions.Options; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Microsoft.AspNetCore.Http +{ + public class SignalRJwtTokenMiddleware : IMiddleware, ITransientDependency + { + protected AbpAspNetCoreSignalRJwtTokenMapPathOptions Options { get; } + + public SignalRJwtTokenMiddleware(IOptions options) + { + Options = options.Value; + } + + public async Task InvokeAsync(HttpContext context, RequestDelegate next) + { + if (Options.MapJwtTokenPaths.Any(path => context.Request.Path.StartsWithSegments(path))) + { + if (context.User.Identity?.IsAuthenticated != true) + { + if (context.Request.Query.TryGetValue("access_token", out var accessToken)) + { + context.Request.Headers.Add("Authorization", $"Bearer {accessToken}"); + } + + } + } + //if (context.Request.Path.StartsWithSegments("/signalr-hubs/")) + //{ + // if (context.User.Identity?.IsAuthenticated != true) + // { + // if (context.Request.Query.TryGetValue("access_token", out var accessToken)) + // { + // context.Request.Headers.Add("Authorization", $"Bearer {accessToken}"); + // } + + // } + //} + await next(context); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN.Abp.IM.SignalR.csproj b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN.Abp.IM.SignalR.csproj index a5f0374fb..f7a1552f9 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN.Abp.IM.SignalR.csproj +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN.Abp.IM.SignalR.csproj @@ -9,9 +9,11 @@ + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs index 6d2bcdc75..1708965fd 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.RealTime; +using LINGYUN.Abp.AspNetCore.SignalR.JwtToken; +using LINGYUN.Abp.RealTime; using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.Modularity; @@ -6,9 +7,16 @@ namespace LINGYUN.Abp.IM.SignalR { [DependsOn( typeof(AbpRealTimeModule), - typeof(AbpAspNetCoreSignalRModule))] + typeof(AbpAspNetCoreSignalRModule), + typeof(AbpAspNetCoreSignalRJwtTokenModule))] public class AbpIMSignalRModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.MapPath("messages"); + }); + } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs similarity index 58% rename from aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs rename to aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs index cf47eeaa5..84a6559ad 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessageHub.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs @@ -1,23 +1,82 @@ -using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.IM.Contract; +using LINGYUN.Abp.IM.Messages; using LINGYUN.Abp.RealTime.Client; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; namespace LINGYUN.Abp.IM.SignalR.Hubs { [Authorize] - public class MessageHub : OnlineClientHubBase + public class MessagesHub : OnlineClientHubBase { - private readonly IMessageStore _messageStore; + protected IFriendStore FriendStore { get; } + protected IMessageStore MessageStore { get; } - public MessageHub( + public MessagesHub( + IFriendStore friendStore, IMessageStore messageStore) { - _messageStore = messageStore; + FriendStore = friendStore; + MessageStore = messageStore; } + + [HubMethodName("LastContactFriends")] + public virtual async Task> GetLastContactFriendsAsync( + Guid? tenantId, + Guid userId, + int skipCount = 0, + int maxResultCount = 10) + { + var myFrientCount = await FriendStore.GetCountAsync(tenantId, userId); + + var lastContractFriends = await FriendStore + .GetLastContactListAsync(tenantId, userId, skipCount, maxResultCount); + + return new PagedResultDto(myFrientCount, lastContractFriends); + } + + [HubMethodName("MyFriends")] + public virtual async Task> GetMyFriendsAsync( + Guid? tenantId, + Guid userId, + string filter = "", + string sorting = nameof(UserFriend.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10) + { + var myFrientCount = await FriendStore.GetCountAsync(tenantId, userId); + + var myFriends = await FriendStore + .GetListAsync(tenantId, userId, filter, sorting, reverse, skipCount, maxResultCount); + + return new PagedResultDto(myFrientCount, myFriends); + } + + [HubMethodName("AddFriend")] + public virtual async Task AddFriendAsync( + Guid? tenantId, + Guid userId, + Guid friendId, + string remarkName = "") + { + await FriendStore.AddMemberAsync(tenantId, userId, friendId, remarkName); + } + + [HubMethodName("RemoveFriend")] + public virtual async Task RemoveFriendAsync( + Guid? tenantId, + Guid userId, + Guid friendId, + string remarkName = "") + { + await FriendStore.RemoveMemberAsync(tenantId, userId, friendId); + } + /// /// 客户端调用发送消息方法 /// @@ -27,7 +86,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs public virtual async Task SendMessageAsync(ChatMessage chatMessage) { // 持久化 - await _messageStore.StoreMessageAsync(chatMessage); + await MessageStore.StoreMessageAsync(chatMessage); try { diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs index 380c90669..dc804e5c6 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs @@ -16,13 +16,13 @@ namespace LINGYUN.Abp.IM.SignalR.Messages private readonly IOnlineClientManager _onlineClientManager; - private readonly IHubContext _hubContext; + private readonly IHubContext _hubContext; private readonly IMessageStore _messageStore; public SignalRMessageSender( IOnlineClientManager onlineClientManager, - IHubContext hubContext, + IHubContext hubContext, IMessageStore messageStore) { _hubContext = hubContext; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs new file mode 100644 index 000000000..102fc7ef3 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.IM.Contract +{ + public interface IFriendStore + { + /// + /// 获取好友数量 + /// + /// + /// + /// + /// + Task GetCountAsync( + Guid? tenantId, + Guid userId, + string filter = ""); + /// + /// 获取好友列表 + /// + /// + /// + /// + /// + /// + /// + /// + /// + Task> GetListAsync( + Guid? tenantId, + Guid userId, + string filter = "", + string sorting = nameof(UserFriend.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10); + /// + /// 获取最近联系好友列表 + /// + /// + /// + /// + /// + /// + Task> GetLastContactListAsync( + Guid? tenantId, + Guid userId, + int skipCount = 0, + int maxResultCount = 10); + /// + /// 获取好友信息 + /// + /// + /// + /// + /// + Task GetMemberAsync( + Guid? tenantId, + Guid userId, + Guid friendId); + /// + /// 添加好友 + /// + /// + /// + /// + /// + /// + Task AddMemberAsync( + Guid? tenantId, + Guid userId, + Guid friendId, + string remarkName = ""); + /// + /// 移除好友 + /// + /// + /// + /// + /// + Task RemoveMemberAsync( + Guid? tenantId, + Guid userId, + Guid friendId); + /// + /// 添加黑名单 + /// + /// + /// + /// + /// + Task AddShieldMemberAsync( + Guid? tenantId, + Guid userId, + Guid friendId); + /// + /// 移除黑名单 + /// + /// + /// + /// + /// + Task RemoveShieldMemberAsync( + Guid? tenantId, + Guid userId, + Guid friendId); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/UserFriend.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/UserFriend.cs new file mode 100644 index 000000000..394ba4634 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/UserFriend.cs @@ -0,0 +1,28 @@ +using System; + +namespace LINGYUN.Abp.IM.Contract +{ + public class UserFriend : UserCard + { + /// + /// 好友标识 + /// + public Guid FriendId { get; set; } + /// + /// 已添加黑名单 + /// + public bool Black { get; set; } + /// + /// 特别关注 + /// + public bool SpecialFocus { get; set; } + /// + /// 消息免打扰 + /// + public bool DontDisturb { get; set; } + /// + /// 备注名称 + /// + public string RemarkName { get; set; } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/GroupUserCard.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/GroupUserCard.cs index ff6315a5b..f41d84064 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/GroupUserCard.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/GroupUserCard.cs @@ -1,22 +1,12 @@ -using System.Collections.Generic; -using System.Linq; - -namespace LINGYUN.Abp.IM.Group +namespace LINGYUN.Abp.IM.Group { public class GroupUserCard : UserCard { public long GroupId { get; set; } public bool IsAdmin { get; set; } public bool IsSuperAdmin { get; set; } - public IDictionary Permissions { get; set; } public GroupUserCard() { - Permissions = new Dictionary(); - } - - public bool IsGrant(string key) - { - return Permissions.Any(x => x.Equals(key) && x.Value); } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs index ccd152c80..670f55eba 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs @@ -22,20 +22,19 @@ namespace LINGYUN.Abp.IM.Group /// Task> GetUserGroupsAsync(Guid? tenantId, Guid userId); /// - /// 获取通讯组所有用户 + /// 获取群组成员列表 /// /// /// /// - Task> GetGroupUsersAsync(Guid? tenantId, long groupId); + Task> GetMembersAsync(Guid? tenantId, long groupId); /// - /// 获取通讯组用户数 + /// 获取群组成员数 /// /// /// - /// /// - Task GetGroupUsersCountAsync(Guid? tenantId, long groupId, string filter = ""); + Task GetMembersCountAsync(Guid? tenantId, long groupId); /// /// 获取通讯组用户 /// @@ -46,7 +45,13 @@ namespace LINGYUN.Abp.IM.Group /// /// /// - Task> GetGroupUsersAsync(Guid? tenantId, long groupId, string filter = "", string sorting = nameof(UserGroup.UserId), int skipCount = 1, int maxResultCount = 10); + Task> GetMembersAsync( + Guid? tenantId, + long groupId, + string sorting = nameof(GroupUserCard.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10); /// /// 用户加入通讯组 /// diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/IUserCardFinder.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/IUserCardFinder.cs new file mode 100644 index 000000000..cdbe9834c --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/IUserCardFinder.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.IM +{ + /// + /// IM用户资料查找接口 + /// + public interface IUserCardFinder + { + /// + /// 查询IM用户数量 + /// + /// + /// 用户名称 + /// 起止年龄 + /// 起止年龄 + /// 性别 + /// + Task GetCountAsync( + Guid? tenantId, + string findUserName = "", + int? startAge = null, + int? endAge = null, + Sex? sex = null); + /// + /// 查询IM用户列表 + /// + /// + /// 用户名称 + /// 起止年龄 + /// 起止年龄 + /// 性别 + /// 排序字段 + /// 是否倒序 + /// 起始记录位置 + /// 最大返回数量 + /// + Task> GetListAsync( + Guid? tenantId, + string findUserName = "", + int? startAge = null, + int? endAge = null, + Sex? sex = null, + string sorting = nameof(UserCard.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10); + /// + /// 获取IM用户信息 + /// + /// + /// + /// + Task GetMemberAsync( + Guid? tenantId, + Guid findUserId); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs index abc64135e..8cdbf63ac 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs @@ -22,15 +22,32 @@ namespace LINGYUN.Abp.IM.Messages /// /// /// - Task GetGroupMessageCountAsync(Guid? tenantId, long groupId, string filter = "", MessageType? type = null); + Task GetGroupMessageCountAsync( + Guid? tenantId, + long groupId, + string filter = "", + MessageType? type = null); /// /// 获取群组聊天记录 /// /// - /// + /// + /// + /// + /// + /// + /// /// /// - Task> GetGroupMessageAsync(Guid? tenantId, long groupId, string filter = "", string sorting = nameof(ChatMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10); + Task> GetGroupMessageAsync( + Guid? tenantId, + long groupId, + string filter = "", + string sorting = nameof(ChatMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10); /// /// 获取与某个用户的聊天记录总数 /// @@ -40,7 +57,12 @@ namespace LINGYUN.Abp.IM.Messages /// /// /// - Task GetChatMessageCountAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", MessageType? type = null); + Task GetChatMessageCountAsync( + Guid? tenantId, + Guid sendUserId, + Guid receiveUserId, + string filter = "", + MessageType? type = null); /// /// 获取与某个用户的聊天记录 /// @@ -48,6 +70,15 @@ namespace LINGYUN.Abp.IM.Messages /// /// /// - Task> GetChatMessageAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", string sorting = nameof(ChatMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10); + Task> GetChatMessageAsync( + Guid? tenantId, + Guid sendUserId, + Guid receiveUserId, + string filter = "", + string sorting = nameof(ChatMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10); } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Sex.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Sex.cs new file mode 100644 index 000000000..9421daaa5 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Sex.cs @@ -0,0 +1,9 @@ +namespace LINGYUN.Abp.IM +{ + public enum Sex + { + Male, + Female, + Other + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/UserCard.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/UserCard.cs index ef6b03503..ba243271e 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/UserCard.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/UserCard.cs @@ -5,15 +5,16 @@ namespace LINGYUN.Abp.IM public class UserCard { public Guid? TenantId { get; set; } + public Guid UserId { get; set; } - #region 下一个版本细粒度的用户资料 与Identity集成 + #region 细粒度的用户资料 public string UserName { get; set; } /// /// 头像 /// - public string AvatarlUrl { get; set; } + public string AvatarUrl { get; set; } /// /// 昵称 /// @@ -21,27 +22,23 @@ namespace LINGYUN.Abp.IM /// /// 年龄 /// - public int Arg { get; set; } + public int Age { get; set; } /// /// 性别 /// - public string Sex { get; set; } - /// - /// 国家 - /// - public string Countriy { get; set; } + public Sex Sex { get; set; } /// - /// 省份 + /// 签名 /// - public string Province { get; set; } + public string Sign { get; set; } /// - /// 城市 + /// 说明 /// - public string City { get; set; } + public string Description { get; set; } /// - /// 签名 + /// 生日 /// - public string Sign { get; set; } + public DateTime? Birthday { get; set; } #endregion } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN.Abp.Notifications.SignalR.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN.Abp.Notifications.SignalR.csproj index 19c1f208f..624125a8a 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN.Abp.Notifications.SignalR.csproj +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN.Abp.Notifications.SignalR.csproj @@ -13,6 +13,7 @@ + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs index 572ab75c3..130a9fd30 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.RealTime; +using LINGYUN.Abp.AspNetCore.SignalR.JwtToken; +using LINGYUN.Abp.RealTime; using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.Modularity; @@ -7,7 +8,8 @@ namespace LINGYUN.Abp.Notifications.SignalR [DependsOn( typeof(AbpRealTimeModule), typeof(AbpNotificationModule), - typeof(AbpAspNetCoreSignalRModule))] + typeof(AbpAspNetCoreSignalRModule), + typeof(AbpAspNetCoreSignalRJwtTokenModule))] public class AbpNotificationsSignalRModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) @@ -16,6 +18,11 @@ namespace LINGYUN.Abp.Notifications.SignalR { options.PublishProviders.Add(); }); + + Configure(options => + { + options.MapPath("notifications"); + }); } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Http/SignalRJwtTokenMiddleware.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Http/SignalRJwtTokenMiddleware.cs deleted file mode 100644 index 3941222b6..000000000 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/Microsoft/AspNetCore/Http/SignalRJwtTokenMiddleware.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; - -namespace Microsoft.AspNetCore.Http -{ - public class SignalRJwtTokenMiddleware : IMiddleware, ITransientDependency - { - public async Task InvokeAsync(HttpContext context, RequestDelegate next) - { - // 仅针对自定义的SignalR hub - if (context.Request.Path.StartsWithSegments("/signalr-hubs/notifications")) - { - if (context.User.Identity?.IsAuthenticated != true) - { - if (context.Request.Query.TryGetValue("access_token", out var accessToken)) - { - context.Request.Headers.Add("Authorization", $"Bearer {accessToken}"); - } - - } - } - await next(context); - } - } -} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupMessageGetByPagedDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupMessageGetByPagedDto.cs index 6c64ff096..82ec7c4a5 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupMessageGetByPagedDto.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupMessageGetByPagedDto.cs @@ -8,6 +8,7 @@ namespace LINGYUN.Abp.MessageService.Chat { [Required] public long GroupId { get; set; } + public bool Reverse { get; set; } public string Filter { get; set; } public MessageType? MessageType { get; set; } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupUserGetByPagedDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupUserGetByPagedDto.cs index 03f52b729..3441332c8 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupUserGetByPagedDto.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/GroupUserGetByPagedDto.cs @@ -8,6 +8,8 @@ namespace LINGYUN.Abp.MessageService.Chat [Required] public long GroupId { get; set; } + public bool Reverse { get; set; } + public string Filter { get; set; } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendCreateDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendCreateDto.cs new file mode 100644 index 000000000..00192a0ae --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendCreateDto.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.MessageService.Chat +{ + public class MyFriendCreateDto : MyFriendOperationDto + { + public string RemarkName { get; set; } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendGetByPagedDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendGetByPagedDto.cs new file mode 100644 index 000000000..ae27bef2b --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendGetByPagedDto.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class MyFriendGetByPagedDto : PagedAndSortedResultRequestDto + { + public string Filter { get; set; } + + public bool Reverse { get; set; } + } + + public class MyLastContractFriendGetByPagedDto : PagedResultRequestDto + { + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendOperationDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendOperationDto.cs new file mode 100644 index 000000000..4b1021666 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendOperationDto.cs @@ -0,0 +1,11 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class MyFriendOperationDto + { + [Required] + public Guid FriendId { get; set; } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/UserMessageGetByPagedDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/UserMessageGetByPagedDto.cs index 444dfaf37..514e5decc 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/UserMessageGetByPagedDto.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/UserMessageGetByPagedDto.cs @@ -9,6 +9,7 @@ namespace LINGYUN.Abp.MessageService.Chat { [Required] public Guid ReceiveUserId { get; set; } + public bool Reverse { get; set; } public string Filter { get; set; } public MessageType? MessageType { get; set; } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IChatAppService.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IChatAppService.cs index 1180b0582..befeb27ad 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IChatAppService.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IChatAppService.cs @@ -30,7 +30,7 @@ namespace LINGYUN.Abp.MessageService.Chat /// /// /// - Task> GetGroupUsersAsync(GroupUserGetByPagedDto groupUserGetByPaged); + Task> GetGroupUsersAsync(GroupUserGetByPagedDto groupUserGetByPaged); /// /// 处理用户群组申请 /// diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IMyFriendAppService.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IMyFriendAppService.cs new file mode 100644 index 000000000..58c3c7c4c --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IMyFriendAppService.cs @@ -0,0 +1,18 @@ +using LINGYUN.Abp.IM.Contract; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public interface IMyFriendAppService : IApplicationService + { + Task> GetMyFriendsAsync(MyFriendGetByPagedDto input); + + Task> GetLastContactFriendsAsync(PagedResultRequestDto input); + + Task CreateAsync(MyFriendCreateDto input); + + Task DeleteAsync(MyFriendOperationDto input); + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/ChatAppService.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/ChatAppService.cs index a0ecd69a9..e5c509afd 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/ChatAppService.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/ChatAppService.cs @@ -1,5 +1,6 @@ using LINGYUN.Abp.IM.Group; using LINGYUN.Abp.IM.Messages; +using Microsoft.AspNetCore.Authorization; using System.Collections.Immutable; using System.Threading.Tasks; using Volo.Abp; @@ -25,6 +26,7 @@ namespace LINGYUN.Abp.MessageService.Chat _userGroupStore = userGroupStore; } + [Authorize] public virtual async Task> GetMyChatMessageAsync(UserMessageGetByPagedDto userMessageGetByPaged) { var chatMessageCount = await _messageStore @@ -33,38 +35,41 @@ namespace LINGYUN.Abp.MessageService.Chat var chatMessages = await _messageStore .GetChatMessageAsync(CurrentTenant.Id, CurrentUser.GetId(), userMessageGetByPaged.ReceiveUserId, - userMessageGetByPaged.Filter, userMessageGetByPaged.Sorting, userMessageGetByPaged.MessageType, - userMessageGetByPaged.SkipCount, userMessageGetByPaged.MaxResultCount); + userMessageGetByPaged.Filter, userMessageGetByPaged.Sorting, userMessageGetByPaged.Reverse, + userMessageGetByPaged.MessageType, userMessageGetByPaged.SkipCount, userMessageGetByPaged.MaxResultCount); return new PagedResultDto(chatMessageCount, chatMessages); } public virtual async Task> GetGroupMessageAsync(GroupMessageGetByPagedDto groupMessageGetByPaged) { + // TODO: 增加验证,用户不在群组却来查询这个群组消息,是非法客户端操作 + var groupMessageCount = await _messageStore .GetGroupMessageCountAsync(CurrentTenant.Id, groupMessageGetByPaged.GroupId, groupMessageGetByPaged.Filter, groupMessageGetByPaged.MessageType); var groupMessages = await _messageStore .GetGroupMessageAsync(CurrentTenant.Id, groupMessageGetByPaged.GroupId, - groupMessageGetByPaged.Filter, groupMessageGetByPaged.Sorting, groupMessageGetByPaged.MessageType, - groupMessageGetByPaged.SkipCount, groupMessageGetByPaged.MaxResultCount); + groupMessageGetByPaged.Filter, groupMessageGetByPaged.Sorting, groupMessageGetByPaged.Reverse, + groupMessageGetByPaged.MessageType, groupMessageGetByPaged.SkipCount, groupMessageGetByPaged.MaxResultCount); return new PagedResultDto(groupMessageCount, groupMessages); } - public virtual async Task> GetGroupUsersAsync(GroupUserGetByPagedDto groupUserGetByPaged) + public virtual async Task> GetGroupUsersAsync(GroupUserGetByPagedDto groupUserGetByPaged) { - var groupUserCount = await _userGroupStore.GetGroupUsersCountAsync(CurrentTenant.Id, - groupUserGetByPaged.GroupId, groupUserGetByPaged.Filter); + var groupUserCardCount = await _userGroupStore + .GetMembersCountAsync(CurrentTenant.Id, groupUserGetByPaged.GroupId); - var groupUsers = await _userGroupStore.GetGroupUsersAsync(CurrentTenant.Id, - groupUserGetByPaged.GroupId, groupUserGetByPaged.Filter, groupUserGetByPaged.Sorting, + var groupUserCards = await _userGroupStore.GetMembersAsync(CurrentTenant.Id, + groupUserGetByPaged.GroupId, groupUserGetByPaged.Sorting, groupUserGetByPaged.Reverse, groupUserGetByPaged.SkipCount, groupUserGetByPaged.MaxResultCount); - return new PagedResultDto(groupUserCount, groupUsers); + return new PagedResultDto(groupUserCardCount, groupUserCards); } + [Authorize] public virtual async Task> GetMyGroupsAsync() { var myGroups = await _userGroupStore.GetUserGroupsAsync(CurrentTenant.Id, CurrentUser.GetId()); @@ -81,7 +86,7 @@ namespace LINGYUN.Abp.MessageService.Chat // 当前登录用户不再用户组 throw new UserFriendlyException(""); } - if (!myGroupCard.IsGrant(nameof(ChatGroupAdmin.AllowAddPeople))) + if (!myGroupCard.IsAdmin) { // 当前登录用户没有加人权限 throw new UserFriendlyException(""); @@ -99,7 +104,7 @@ namespace LINGYUN.Abp.MessageService.Chat // 当前登录用户不再用户组 throw new UserFriendlyException(""); } - if (!myGroupCard.IsGrant(nameof(ChatGroupAdmin.AllowKickPeople))) + if (!myGroupCard.IsAdmin) { // 当前登录用户没有踢人权限 throw new UserFriendlyException(""); diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/MyFriendAppService.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/MyFriendAppService.cs new file mode 100644 index 000000000..b11ffcda1 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Chat/MyFriendAppService.cs @@ -0,0 +1,53 @@ +using LINGYUN.Abp.IM.Contract; +using Microsoft.AspNetCore.Authorization; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Users; + +namespace LINGYUN.Abp.MessageService.Chat +{ + [Authorize] + public class MyFriendAppService : ApplicationService, IMyFriendAppService + { + protected IFriendStore FriendStore { get; } + + public MyFriendAppService(IFriendStore friendStore) + { + FriendStore = friendStore; + } + + public virtual async Task CreateAsync(MyFriendCreateDto input) + { + await FriendStore.AddMemberAsync(CurrentTenant.Id, CurrentUser.GetId(), input.FriendId, input.RemarkName); + } + + public virtual async Task DeleteAsync(MyFriendOperationDto input) + { + await FriendStore.RemoveMemberAsync(CurrentTenant.Id, CurrentUser.GetId(), input.FriendId); + } + + public virtual async Task> GetLastContactFriendsAsync(PagedResultRequestDto input) + { + var myFrientCount = await FriendStore.GetCountAsync(CurrentTenant.Id, CurrentUser.GetId()); + + var myFriends = await FriendStore + .GetLastContactListAsync(CurrentTenant.Id, CurrentUser.GetId(), + input.SkipCount, input.MaxResultCount); + + return new PagedResultDto(myFrientCount, myFriends); + } + + public virtual async Task> GetMyFriendsAsync(MyFriendGetByPagedDto input) + { + var myFrientCount = await FriendStore.GetCountAsync(CurrentTenant.Id, CurrentUser.GetId()); + + var myFriends = await FriendStore + .GetListAsync(CurrentTenant.Id, CurrentUser.GetId(), + input.Filter, input.Sorting, input.Reverse, + input.SkipCount, input.MaxResultCount); + + return new PagedResultDto(myFrientCount, myFriends); + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN.Abp.MessageService.Domain.Shared.csproj b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN.Abp.MessageService.Domain.Shared.csproj index 57cd2fec7..5c97ed0c0 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN.Abp.MessageService.Domain.Shared.csproj +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN.Abp.MessageService.Domain.Shared.csproj @@ -9,6 +9,7 @@ + diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Chat/UserChatCardConsts.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Chat/UserChatCardConsts.cs new file mode 100644 index 000000000..9a29d2986 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Chat/UserChatCardConsts.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Users; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class UserChatCardConsts + { + public static int MaxUserNameLength { get; set; } = AbpUserConsts.MaxUserNameLength; + public static int MaxSignLength { get; set; } = 30; + public static int MaxNickNameLength { get; set; } = AbpUserConsts.MaxUserNameLength; + public static int MaxDescriptionLength { get; set; } = 50; + public static int MaxAvatarUrlLength { get; set; } = 512; + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDbProperties.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDbProperties.cs index 6a87fed45..091a3b76b 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDbProperties.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/AbpMessageServiceDbProperties.cs @@ -5,5 +5,7 @@ public const string DefaultTablePrefix = "App"; public const string DefaultSchema = null; + + public const string ConnectionStringName = "MessageService"; } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatDataSeeder.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatDataSeeder.cs new file mode 100644 index 000000000..9a0532e55 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatDataSeeder.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; +using Volo.Abp.Uow; +using Volo.Abp.Users; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class ChatDataSeeder : IChatDataSeeder, ITransientDependency + { + protected IClock Clock { get; } + protected ICurrentTenant CurrentTenant { get; } + protected IUserChatCardRepository UserChatCardRepository { get; } + protected IUserChatSettingRepository UserChatSettingRepository { get; } + public ChatDataSeeder( + IClock clock, + ICurrentTenant currentTenant, + IUserChatCardRepository userChatCardRepository, + IUserChatSettingRepository userChatSettingRepository) + { + Clock = clock; + CurrentTenant = currentTenant; + UserChatCardRepository = userChatCardRepository; + UserChatSettingRepository = userChatSettingRepository; + } + + [UnitOfWork] + public virtual async Task SeedAsync(IUserData user) + { + using (CurrentTenant.Change(user.TenantId)) + { + var userHasOpendIm = await UserChatSettingRepository.UserHasOpendImAsync(user.Id); + if (!userHasOpendIm) + { + var userChatSetting = new UserChatSetting(user.Id, user.TenantId); + + await UserChatSettingRepository.InsertAsync(userChatSetting); + + var userChatCard = new UserChatCard(user.Id, user.UserName, IM.Sex.Male, user.UserName, tenantId: user.TenantId) + { + CreationTime = Clock.Now, + CreatorId = user.Id + }; + + await UserChatCardRepository.InsertAsync(userChatCard); + } + } + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroup.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroup.cs index cb1eb1136..ee22667ba 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroup.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroup.cs @@ -14,6 +14,10 @@ namespace LINGYUN.Abp.MessageService.Chat /// public virtual Guid? TenantId { get; protected set; } /// + /// 群主 + /// + public virtual Guid AdminUserId { get; protected set; } + /// /// 群组标识 /// public virtual long GroupId { get; protected set; } @@ -28,11 +32,11 @@ namespace LINGYUN.Abp.MessageService.Chat /// /// 群组地址 /// - public virtual string Address { get; protected set; } + public virtual string Address { get; set; } /// /// 群组公告 /// - public virtual string Notice { get; protected set; } + public virtual string Notice { get; set; } /// /// 最大用户数量 /// @@ -52,23 +56,20 @@ namespace LINGYUN.Abp.MessageService.Chat protected ChatGroup() { } - public ChatGroup(long id, string name, string tag = "", string address = "", int maxUserCount = 200) + public ChatGroup( + long id, + Guid adminUserId, + string name, + string tag = "", + string address = "", + int maxUserCount = 200) { GroupId = id; + AdminUserId = adminUserId; Name = name; Tag = tag; Address = address; MaxUserCount = maxUserCount; } - - public void ChangeAddress(string address) - { - Address = address; - } - - public void SetNotice(string notice) - { - Notice = notice; - } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroupAdmin.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroupAdmin.cs deleted file mode 100644 index 6ab195ccf..000000000 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/ChatGroupAdmin.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace LINGYUN.Abp.MessageService.Chat -{ - /// - /// 群管理员 - /// - public class ChatGroupAdmin : AuditedEntity, IMultiTenant - { - /// - /// 租户 - /// - public virtual Guid? TenantId { get; protected set; } - /// - /// 群组标识 - /// - public virtual long GroupId { get; protected set; } - /// - /// 管理员用户 - /// - public virtual Guid UserId { get; protected set; } - /// - /// 是否群主 - /// - public virtual bool IsSuperAdmin { get; protected set; } - /// - /// 允许禁言 - /// - public virtual bool AllowSilence { get; set; } - /// - /// 允许踢人 - /// - public virtual bool AllowKickPeople { get; set; } - /// - /// 允许加人 - /// - public virtual bool AllowAddPeople { get; set; } - /// - /// 允许发送群公告 - /// - public virtual bool AllowSendNotice { get; set; } - /// - /// 允许解散群组 - /// - public virtual bool AllowDissolveGroup { get; set; } - protected ChatGroupAdmin() { } - public ChatGroupAdmin(long groupId, Guid userId, bool isSuperAdmin = false) - { - GroupId = groupId; - UserId = userId; - AllowSilence = true; - AllowKickPeople = true; - AllowAddPeople = true; - AllowSendNotice = true; - SetSuperAdmin(isSuperAdmin); - } - - public void SetSuperAdmin(bool isSuperAdmin = false) - { - IsSuperAdmin = isSuperAdmin; - if (isSuperAdmin) - { - AllowDissolveGroup = true; - } - } - } -} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/FriendStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/FriendStore.cs new file mode 100644 index 000000000..e4bd716f7 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/FriendStore.cs @@ -0,0 +1,119 @@ +using LINGYUN.Abp.IM.Contract; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; +using Volo.Abp.Uow; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class FriendStore : DomainService, IFriendStore + { + protected IUserChatFriendRepository UserChatFriendRepository { get; } + + public FriendStore( + IUserChatFriendRepository userChatFriendRepository) + { + UserChatFriendRepository = userChatFriendRepository; + } + + [UnitOfWork] + public virtual async Task AddMemberAsync(Guid? tenantId, Guid userId, Guid friendId, string remarkName = "") + { + using (CurrentTenant.Change(tenantId)) + { + if (!await UserChatFriendRepository.IsAddedAsync(userId, friendId)) + { + var userChatFriend = new UserChatFriend(userId, friendId, remarkName, tenantId) + { + CreationTime = Clock.Now, + CreatorId = userId + }; + + await UserChatFriendRepository.InsertAsync(userChatFriend); + } + } + } + + [UnitOfWork] + public virtual async Task AddShieldMemberAsync(Guid? tenantId, Guid userId, Guid friendId) + { + await ChangeFriendShieldAsync(tenantId, userId, friendId, true); + } + + public virtual async Task GetCountAsync(Guid? tenantId, Guid userId, string filter = "") + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatFriendRepository + .GetMembersCountAsync(userId, filter); + } + } + + public virtual async Task> GetListAsync(Guid? tenantId, Guid userId, string filter = "", string sorting = nameof(UserFriend.UserId), bool reverse = false, int skipCount = 0, int maxResultCount = 10) + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatFriendRepository + .GetMembersAsync(userId, filter, sorting, reverse, + skipCount, maxResultCount); + } + } + + public virtual async Task> GetLastContactListAsync( + Guid? tenantId, + Guid userId, + int skipCount = 0, + int maxResultCount = 10) + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatFriendRepository + .GetLastContactMembersAsync(userId, + skipCount, maxResultCount); + } + } + + public virtual async Task GetMemberAsync(Guid? tenantId, Guid userId, Guid friendId) + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatFriendRepository + .GetMemberAsync(userId, friendId); + } + } + + [UnitOfWork] + public virtual async Task RemoveMemberAsync(Guid? tenantId, Guid userId, Guid friendId) + { + using (CurrentTenant.Change(tenantId)) + { + var userChatFriend = await UserChatFriendRepository.FindByUserFriendIdAsync(userId, friendId); + if (userChatFriend != null) + { + await UserChatFriendRepository.DeleteAsync(userChatFriend); + } + } + } + + [UnitOfWork] + public virtual async Task RemoveShieldMemberAsync(Guid? tenantId, Guid userId, Guid friendId) + { + await ChangeFriendShieldAsync(tenantId, userId, friendId, false); + } + + + protected virtual async Task ChangeFriendShieldAsync(Guid? tenantId, Guid userId, Guid friendId, bool isBlack = false) + { + using (CurrentTenant.Change(tenantId)) + { + var userChatFriend = await UserChatFriendRepository.FindByUserFriendIdAsync(userId, friendId); + if (userChatFriend != null) + { + userChatFriend.Black = isBlack; + await UserChatFriendRepository.UpdateAsync(userChatFriend); + } + } + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IChatDataSeeder.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IChatDataSeeder.cs new file mode 100644 index 000000000..03ca8b7e3 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IChatDataSeeder.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using Volo.Abp.Users; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public interface IChatDataSeeder + { + Task SeedAsync( + IUserData user); + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IGroupRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IGroupRepository.cs index 845ceeb63..568845459 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IGroupRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IGroupRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -13,10 +14,18 @@ namespace LINGYUN.Abp.MessageService.Chat /// /// /// - Task UserHasBlackedAsync(long id, Guid formUserId); + Task UserHasBlackedAsync( + long id, + Guid formUserId, + CancellationToken cancellationToken = default); - Task GetByIdAsync(long id); + Task GetByIdAsync( + long id, + CancellationToken cancellationToken = default); + + Task> GetGroupAdminAsync( + long id, + CancellationToken cancellationToken = default); - Task> GetGroupAdminAsync(long id); } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IMessageRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IMessageRepository.cs index de3bf2bef..9c5af2539 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IMessageRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IMessageRepository.cs @@ -1,30 +1,92 @@ using LINGYUN.Abp.IM.Messages; using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace LINGYUN.Abp.MessageService.Chat { public interface IMessageRepository { - Task InsertUserMessageAsync(UserMessage userMessage, bool saveChangs = false); + Task InsertUserMessageAsync( + UserMessage userMessage, + CancellationToken cancellationToken = default); - Task InsertGroupMessageAsync(GroupMessage groupMessage, bool saveChangs = false); + Task InsertGroupMessageAsync( + GroupMessage groupMessage, + CancellationToken cancellationToken = default); - Task GetUserMessageAsync(long id); + Task GetUserMessageAsync( + long id, + CancellationToken cancellationToken = default); - Task GetGroupMessageAsync(long id); + Task GetGroupMessageAsync( + long id, + CancellationToken cancellationToken = default); - Task GetUserMessagesCountAsync(Guid sendUserId, Guid receiveUserId, string filter = "", MessageType? type = null); + Task GetUserMessagesCountAsync( + Guid sendUserId, + Guid receiveUserId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default); - Task> GetUserMessagesAsync(Guid sendUserId, Guid receiveUserId, string filter = "", string sorting = nameof(UserMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10); + Task GetCountAsync( + long groupId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default); - Task GetGroupMessagesCountAsync(long groupId, string filter = "", MessageType? type = null); + Task GetCountAsync( + Guid sendUserId, + Guid receiveUserId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default); - Task> GetGroupMessagesAsync(long groupId, string filter = "", string sorting = nameof(UserMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10); + Task> GetUserMessagesAsync( + Guid sendUserId, + Guid receiveUserId, + string filter = "", + string sorting = nameof(UserMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); - Task GetUserGroupMessagesCountAsync(Guid sendUserId, long groupId, string filter = "", MessageType? type = null); + Task GetGroupMessagesCountAsync( + long groupId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default); - Task> GetUserGroupMessagesAsync(Guid sendUserId, long groupId, string filter = "", string sorting = nameof(UserMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10); + Task> GetGroupMessagesAsync( + long groupId, + string filter = "", + string sorting = nameof(UserMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); + + Task GetUserGroupMessagesCountAsync( + Guid sendUserId, + long groupId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default); + + Task> GetUserGroupMessagesAsync( + Guid sendUserId, + long groupId, + string filter = "", + string sorting = nameof(UserMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatCardRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatCardRepository.cs new file mode 100644 index 000000000..e55c9ab96 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatCardRepository.cs @@ -0,0 +1,38 @@ +using LINGYUN.Abp.IM; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public interface IUserChatCardRepository : IBasicRepository + { + Task CheckUserIdExistsAsync( + Guid userId, + CancellationToken cancellationToken = default); + + Task GetMemberCountAsync( + string findUserName = "", + int? startAge = null, + int? endAge = null, + Sex? sex = null, + CancellationToken cancellationToken = default); + + Task> GetMembersAsync( + string findUserName = "", + int? startAge = null, + int? endAge = null, + Sex? sex = null, + string sorting = nameof(UserChatCard.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); + + Task GetMemberAsync( + Guid findUserId, + CancellationToken cancellationToken = default); + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatFriendRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatFriendRepository.cs new file mode 100644 index 000000000..96cebd7fa --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatFriendRepository.cs @@ -0,0 +1,47 @@ +using LINGYUN.Abp.IM.Contract; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public interface IUserChatFriendRepository : IBasicRepository + { + Task IsAddedAsync( + Guid userId, + Guid frientId, + CancellationToken cancellationToken = default); + + Task FindByUserFriendIdAsync( + Guid userId, + Guid friendId, + CancellationToken cancellationToken = default); + + Task GetMembersCountAsync( + Guid userId, + string filter = "", + CancellationToken cancellationToken = default); + + Task> GetMembersAsync( + Guid userId, + string filter = "", + string sorting = nameof(UserChatFriend.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); + + Task> GetLastContactMembersAsync( + Guid userId, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); + + Task GetMemberAsync( + Guid userId, + Guid friendId, + CancellationToken cancellationToken = default); + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatGroupRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatGroupRepository.cs index bcf1bfdfb..f7f04df57 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatGroupRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/IUserChatGroupRepository.cs @@ -1,6 +1,7 @@ using LINGYUN.Abp.IM.Group; using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -9,23 +10,71 @@ namespace LINGYUN.Abp.MessageService.Chat public interface IUserChatGroupRepository : IBasicRepository { /// - /// 用户是否在组里 + /// 成员是否在群组里 /// /// /// /// - Task UserHasInGroupAsync(long groupId, Guid userId); - - Task GetUserGroupAsync(long groupId, Guid userId); - - Task GetGroupUserCardAsync(long groupId, Guid userId); - - Task> GetGroupUsersAsync(long groupId); - - Task GetGroupUsersCountAsync(long groupId, string filter = ""); - - Task> GetGroupUsersAsync(long groupId, string filter = "", string sorting = nameof(UserGroup.UserId), int skipCount = 1, int maxResultCount = 10); - - Task> GetUserGroupsAsync(Guid userId); + Task MemberHasInGroupAsync( + long groupId, + Guid userId, + CancellationToken cancellationToken = default); + /// + /// 获取群组成员 + /// + /// + /// + /// + /// + Task GetMemberAsync( + long groupId, + Guid userId, + CancellationToken cancellationToken = default); + /// + /// 获取群组成员数 + /// + /// + /// + /// + Task GetMembersCountAsync( + long groupId, + CancellationToken cancellationToken = default); + /// + /// 获取群组成员列表 + /// + /// + /// + /// + /// + /// + /// + /// + Task> GetMembersAsync( + long groupId, + string sorting = nameof(UserChatCard.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default); + /// + /// 获取成员所在群组列表 + /// + /// + /// + /// + Task> GetMemberGroupsAsync( + Guid userId, + CancellationToken cancellationToken = default); + /// + /// 从群组中移除成员 + /// + /// + /// + /// + /// + Task RemoveMemberFormGroupAsync( + long groupId, + Guid userId, + CancellationToken cancellationToken = default); } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageStore.cs index af3f84572..b11bbc06a 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageStore.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/MessageStore.cs @@ -54,31 +54,72 @@ namespace LINGYUN.Abp.MessageService.Chat } } - public async Task> GetGroupMessageAsync(Guid? tenantId, long groupId, string filter = "", - string sorting = nameof(ChatMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10) + public async Task> GetGroupMessageAsync( + Guid? tenantId, + long groupId, + string filter = "", + string sorting = nameof(ChatMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10) { using (CurrentTenant.Change(tenantId)) { var groupMessages = await MessageRepository - .GetGroupMessagesAsync(groupId, filter, sorting, type, skipCount, maxResultCount); + .GetGroupMessagesAsync(groupId, filter, sorting, reverse, type, skipCount, maxResultCount); var chatMessages = ObjectMapper.Map, List>(groupMessages); return chatMessages; } } - public async Task> GetChatMessageAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", - string sorting = nameof(ChatMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10) + public async Task> GetChatMessageAsync( + Guid? tenantId, + Guid sendUserId, + Guid receiveUserId, + string filter = "", + string sorting = nameof(ChatMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10) { using (CurrentTenant.Change(tenantId)) { - var userMessages = await MessageRepository.GetUserMessagesAsync(sendUserId, receiveUserId, filter, sorting, type, skipCount, maxResultCount); + var userMessages = await MessageRepository + .GetUserMessagesAsync(sendUserId, receiveUserId, filter, sorting, reverse, type, skipCount, maxResultCount); var chatMessages = ObjectMapper.Map, List>(userMessages); return chatMessages; } } - + + public virtual async Task GetGroupMessageCountAsync( + Guid? tenantId, + long groupId, + string filter = "", + MessageType? type = null) + { + using (CurrentTenant.Change(tenantId)) + { + return await MessageRepository.GetCountAsync(groupId, filter, type); + } + } + + public virtual async Task GetChatMessageCountAsync( + Guid? tenantId, + Guid sendUserId, + Guid receiveUserId, + string filter = "", + MessageType? type = null) + { + using (CurrentTenant.Change(tenantId)) + { + return await MessageRepository.GetCountAsync(sendUserId, receiveUserId, filter, type); + } + } + protected virtual async Task StoreUserMessageAsync(ChatMessage chatMessage) { var userHasBlacked = await UserChatSettingRepository @@ -135,15 +176,5 @@ namespace LINGYUN.Abp.MessageService.Chat chatMessage.MessageId = messageId.ToString(); } - - public Task GetGroupMessageCountAsync(Guid? tenantId, long groupId, string filter = "", MessageType? type = null) - { - throw new NotImplementedException(); - } - - public Task GetChatMessageCountAsync(Guid? tenantId, Guid sendUserId, Guid receiveUserId, string filter = "", MessageType? type = null) - { - throw new NotImplementedException(); - } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserCardFinder.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserCardFinder.cs new file mode 100644 index 000000000..661e0b9bb --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserCardFinder.cs @@ -0,0 +1,47 @@ +using LINGYUN.Abp.IM; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class UserCardFinder : DomainService, IUserCardFinder + { + protected IUserChatCardRepository UserChatCardRepository { get; } + + public UserCardFinder( + IUserChatCardRepository userChatCardRepository) + { + UserChatCardRepository = userChatCardRepository; + } + + public virtual async Task GetCountAsync(Guid? tenantId, string findUserName = "", int? startAge = null, int? endAge = null, Sex? sex = null) + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatCardRepository + .GetMemberCountAsync(findUserName, startAge, endAge, sex); + } + } + + public virtual async Task> GetListAsync(Guid? tenantId, string findUserName = "", int? startAge = null, int? endAge = null, Sex? sex = null, string sorting = nameof(UserCard.UserId), bool reverse = false, int skipCount = 0, int maxResultCount = 10) + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatCardRepository + .GetMembersAsync(findUserName, startAge, endAge, sex, + sorting, reverse, skipCount, maxResultCount); + } + } + + public virtual async Task GetMemberAsync(Guid? tenantId, Guid findUserId) + { + using (CurrentTenant.Change(tenantId)) + { + return await UserChatCardRepository + .GetMemberAsync(findUserId); + } + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatCard.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatCard.cs new file mode 100644 index 000000000..46c4eb463 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatCard.cs @@ -0,0 +1,105 @@ +using LINGYUN.Abp.IM; +using LINGYUN.Abp.MessageService.Utils; +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; + +namespace LINGYUN.Abp.MessageService.Chat +{ + /// + /// 用户卡片 + /// + public class UserChatCard : AuditedAggregateRoot, IMultiTenant + { + /// + /// 租户 + /// + public virtual Guid? TenantId { get; protected set; } + /// + /// 用户标识 + /// + public virtual Guid UserId { get; protected set; } + /// + /// 用户名 + /// + public virtual string UserName { get; protected set; } + /// + /// 性别 + /// + public virtual Sex Sex { get; set; } + /// + /// 签名 + /// + public virtual string Sign { get; set; } + /// + /// 昵称 + /// + public virtual string NickName { get; set; } + /// + /// 说明 + /// + public virtual string Description { get; set; } + /// + /// 头像地址 + /// + public virtual string AvatarUrl { get; protected set; } + /// + /// 生日 + /// + public virtual DateTime? Birthday { get; protected set; } + /// + /// 年龄 + /// + public virtual int Age { get; protected set; } + + protected UserChatCard() + { + } + + public UserChatCard( + Guid userId, + string userName, + Sex sex, + string nickName = null, + string avatarUrl = "", + Guid? tenantId = null) + { + Sex = sex; + UserId = userId; + UserName = userName; + NickName = nickName ?? userName; + AvatarUrl = avatarUrl; + TenantId = tenantId; + } + + public void SetBirthday(DateTime birthday, IClock clock) + { + Birthday = birthday; + + Age = DateTimeHelper.CalcAgrByBirthdate(birthday, clock.Now); + } + + public void SetAvatarUrl(string url) + { + AvatarUrl = url; + } + + public UserCard ToUserCard() + { + return new UserCard + { + Age = Age, + AvatarUrl = AvatarUrl, + Birthday = Birthday, + Description = Description, + NickName = NickName, + Sex = Sex, + Sign = Sign, + UserId = UserId, + UserName = UserName, + TenantId = TenantId + }; + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatFriend.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatFriend.cs new file mode 100644 index 000000000..1392955d3 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatFriend.cs @@ -0,0 +1,54 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class UserChatFriend : CreationAuditedEntity, IMultiTenant + { + /// + /// 租户 + /// + public virtual Guid? TenantId { get; protected set; } + /// + /// 用户标识 + /// + public virtual Guid UserId { get; protected set; } + /// + /// 好友标识 + /// + public virtual Guid FrientId { get; protected set; } + /// + /// 已添加黑名单 + /// + public virtual bool Black { get; set; } + /// + /// 消息免打扰 + /// + public virtual bool DontDisturb { get; set; } + /// + /// 特别关注 + /// + public virtual bool SpecialFocus { get; set; } + /// + /// 备注名称 + /// + public virtual string RemarkName { get; set; } + + protected UserChatFriend() + { + } + + public UserChatFriend( + Guid userId, + Guid friendId, + string remarkName = "", + Guid? tenantId = null) + { + UserId = userId; + FrientId = friendId; + RemarkName = remarkName; + TenantId = tenantId; + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupCard.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupCard.cs new file mode 100644 index 000000000..a1732631f --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupCard.cs @@ -0,0 +1,74 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; + +namespace LINGYUN.Abp.MessageService.Chat +{ + /// + /// 用户群组卡片 + /// + public class UserGroupCard : AuditedAggregateRoot, IMultiTenant + { + /// + /// 租户 + /// + public virtual Guid? TenantId { get; protected set; } + /// + /// 用户标识 + /// + public virtual Guid UserId { get; protected set; } + /// + /// 昵称 + /// + public virtual string NickName { get; set; } + /// + /// 是否管理员 + /// + public virtual bool IsAdmin { get; protected set; } + /// + /// 禁言期止 + /// + public virtual DateTime? SilenceEnd { get; protected set; } + protected UserGroupCard() + { + } + public UserGroupCard( + Guid userId, + string nickName = "", + bool isAdmin = false, + DateTime? silenceEnd = null, + Guid? tenantId = null) + { + UserId = userId; + NickName = nickName; + IsAdmin = isAdmin; + SilenceEnd = silenceEnd; + TenantId = tenantId; + } + /// + /// 设置管理员 + /// + /// + public void SetAdmin(bool admin) + { + IsAdmin = admin; + } + /// + /// 禁言 + /// + /// + /// + public void Silence(IClock clock, double seconds) + { + SilenceEnd = clock.Now.AddSeconds(seconds); + } + /// + /// 解除禁言 + /// + public void UnSilence() + { + SilenceEnd = null; + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupStore.cs index 89a5881b1..1a7f935b9 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupStore.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserGroupStore.cs @@ -31,7 +31,7 @@ namespace LINGYUN.Abp.MessageService.Chat { using (CurrentTenant.Change(tenantId)) { - var userHasInGroup = await UserChatGroupRepository.UserHasInGroupAsync(groupId, userId); + var userHasInGroup = await UserChatGroupRepository.MemberHasInGroupAsync(groupId, userId); if (!userHasInGroup) { var userGroup = new UserChatGroup(groupId, userId, acceptUserId, tenantId); @@ -48,19 +48,17 @@ namespace LINGYUN.Abp.MessageService.Chat { using (CurrentTenant.Change(tenantId)) { - var groupUserCard = await UserChatGroupRepository.GetGroupUserCardAsync(groupId, userId); + var groupUserCard = await UserChatGroupRepository.GetMemberAsync(groupId, userId); return groupUserCard; } } - public async Task> GetGroupUsersAsync(Guid? tenantId, long groupId) + public async Task> GetMembersAsync(Guid? tenantId, long groupId) { using (CurrentTenant.Change(tenantId)) { - var userGroups = await UserChatGroupRepository.GetGroupUsersAsync(groupId); - - return userGroups; + return await UserChatGroupRepository.GetMembersAsync(groupId); } } @@ -68,9 +66,7 @@ namespace LINGYUN.Abp.MessageService.Chat { using (CurrentTenant.Change(tenantId)) { - var groups = await UserChatGroupRepository.GetUserGroupsAsync(userId); - - return groups; + return await UserChatGroupRepository.GetMemberGroupsAsync(userId); } } @@ -81,31 +77,32 @@ namespace LINGYUN.Abp.MessageService.Chat { using (CurrentTenant.Change(tenantId)) { - var userGroup = await UserChatGroupRepository.GetUserGroupAsync(groupId, userId); - - if(userGroup != null) - { - await UserChatGroupRepository.DeleteAsync(userGroup); + await UserChatGroupRepository.RemoveMemberFormGroupAsync(groupId, userId); - await unitOfWork.SaveChangesAsync(); - } + await unitOfWork.SaveChangesAsync(); } } } - public async Task GetGroupUsersCountAsync(Guid? tenantId, long groupId, string filter = "") + public async Task GetMembersCountAsync(Guid? tenantId, long groupId) { using (CurrentTenant.Change(tenantId)) { - return await UserChatGroupRepository.GetGroupUsersCountAsync(groupId, filter); + return await UserChatGroupRepository.GetMembersCountAsync(groupId); } } - public async Task> GetGroupUsersAsync(Guid? tenantId, long groupId, string filter = "", string sorting = "UserId", int skipCount = 1, int maxResultCount = 10) + public async Task> GetMembersAsync( + Guid? tenantId, + long groupId, + string sorting = nameof(GroupUserCard.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10) { using (CurrentTenant.Change(tenantId)) { - return await UserChatGroupRepository.GetGroupUsersAsync(groupId, filter, sorting, skipCount, maxResultCount); + return await UserChatGroupRepository.GetMembersAsync(groupId, sorting, reverse, skipCount, maxResultCount); } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateJoinIMEventHandler.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateJoinIMEventHandler.cs index d82153783..7ca3728c6 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateJoinIMEventHandler.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateJoinIMEventHandler.cs @@ -3,47 +3,26 @@ using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.EventBus; -using Volo.Abp.MultiTenancy; -using Volo.Abp.Uow; using Volo.Abp.Users; namespace LINGYUN.Abp.MessageService.EventBus.Distributed { public class UserCreateJoinIMEventHandler : ILocalEventHandler>, ITransientDependency { - private readonly ICurrentTenant _currentTenant; - private readonly IUnitOfWorkManager _unitOfWorkManager; - private readonly IUserChatSettingRepository _userChatSettingRepository; + private readonly IChatDataSeeder _chatDataSeeder; public UserCreateJoinIMEventHandler( - ICurrentTenant currentTenant, - IUnitOfWorkManager unitOfWorkManager, - IUserChatSettingRepository userChatSettingRepository) + IChatDataSeeder chatDataSeeder) { - _currentTenant = currentTenant; - _unitOfWorkManager = unitOfWorkManager; - _userChatSettingRepository = userChatSettingRepository; + _chatDataSeeder = chatDataSeeder; } /// - /// 接收添加用户事件,启用IM模块时增加用户配置 + /// 接收添加用户事件,初始化IM用户种子 /// /// /// public async Task HandleEventAsync(EntityCreatedEventData eventData) { - using (var unitOfWork = _unitOfWorkManager.Begin()) - { - using (_currentTenant.Change(eventData.Entity.TenantId)) - { - var userHasOpendIm = await _userChatSettingRepository.UserHasOpendImAsync(eventData.Entity.Id); - if (!userHasOpendIm) - { - var userChatSetting = new UserChatSetting(eventData.Entity.Id, eventData.Entity.TenantId); - await _userChatSettingRepository.InsertAsync(userChatSetting); - - await unitOfWork.SaveChangesAsync(); - } - } - } + await _chatDataSeeder.SeedAsync(eventData.Entity); } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Utils/DateTimeHelper.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Utils/DateTimeHelper.cs new file mode 100644 index 000000000..9aa6f8e34 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Utils/DateTimeHelper.cs @@ -0,0 +1,17 @@ +using System; + +namespace LINGYUN.Abp.MessageService.Utils +{ + public static class DateTimeHelper + { + public static int CalcAgrByBirthdate(DateTime birthdate, DateTime nowTime) + { + int age = nowTime.Year - birthdate.Year; + if (nowTime.Month < birthdate.Month || (nowTime.Month == birthdate.Month && nowTime.Day < birthdate.Day)) + { + age--; + } + return age < 0 ? 0 : age; + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreGroupRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreGroupRepository.cs index 5701da4d5..5d5bac6b8 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreGroupRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreGroupRepository.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; @@ -10,35 +11,46 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Chat { - public class EfCoreGroupRepository : EfCoreRepository, + public class EfCoreGroupRepository : EfCoreRepository, IGroupRepository, ITransientDependency { public EfCoreGroupRepository( - IDbContextProvider dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } - public async Task GetByIdAsync(long id) + public virtual async Task GetByIdAsync( + long id, + CancellationToken cancellationToken = default) { - return await DbSet.Where(x => x.GroupId.Equals(id)).FirstOrDefaultAsync(); + return await DbSet + .Where(x => x.GroupId.Equals(id)) + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetGroupAdminAsync(long id) + public virtual async Task> GetGroupAdminAsync( + long id, + CancellationToken cancellationToken = default) { var groupAdmins = await (from gp in DbContext.Set() - join gpa in DbContext.Set() - on gp.GroupId equals gpa.GroupId - select gpa) - .Distinct() - .ToListAsync(); + join ucg in DbContext.Set() + on gp.GroupId equals ucg.GroupId + join ugc in DbContext.Set() + on ucg.UserId equals ugc.UserId + where ugc.IsAdmin + select ugc) + .ToListAsync(GetCancellationToken(cancellationToken)); return groupAdmins; } - public async Task UserHasBlackedAsync(long id, Guid formUserId) + public virtual async Task UserHasBlackedAsync( + long id, + Guid formUserId, + CancellationToken cancellationToken = default) { var userHasBlack = await DbContext.Set() - .AnyAsync(x => x.GroupId.Equals(id) && x.ShieldUserId.Equals(formUserId)); + .AnyAsync(x => x.GroupId.Equals(id) && x.ShieldUserId.Equals(formUserId), GetCancellationToken(cancellationToken)); return userHasBlack; } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs index d766e38db..4d0c7a9c5 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; @@ -12,88 +13,153 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Chat { - public class EfCoreMessageRepository : EfCoreRepository, + public class EfCoreMessageRepository : EfCoreRepository, IMessageRepository, ITransientDependency { public EfCoreMessageRepository( - IDbContextProvider dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } - public async Task GetGroupMessageAsync(long id) + public virtual async Task GetGroupMessageAsync( + long id, + CancellationToken cancellationToken = default) { return await DbContext.Set() .Where(x => x.MessageId.Equals(id)) .AsNoTracking() - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetGroupMessagesAsync(long groupId, string filter = "", - string sorting = nameof(UserMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10) + public virtual async Task> GetGroupMessagesAsync( + long groupId, + string filter = "", + string sorting = nameof(UserMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default) { + sorting = reverse ? sorting + " desc" : sorting; var groupMessages = await DbContext.Set() .Distinct() .Where(x => x.GroupId.Equals(groupId)) .WhereIf(type != null, x => x.Type.Equals(type)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) .OrderBy(sorting ?? nameof(GroupMessage.MessageId)) - .Page(skipCount, maxResultCount) + .PageBy(skipCount, maxResultCount) .AsNoTracking() - .ToListAsync(); + .ToListAsync(GetCancellationToken(cancellationToken)); return groupMessages; } - public async Task GetGroupMessagesCountAsync(long groupId, string filter = "", MessageType? type = null) + public virtual async Task GetGroupMessagesCountAsync( + long groupId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default) { var groupMessagesCount = await DbContext.Set() .Distinct() .Where(x => x.GroupId.Equals(groupId)) .WhereIf(type != null, x => x.Type.Equals(type)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) - .LongCountAsync(); + .LongCountAsync(GetCancellationToken(cancellationToken)); return groupMessagesCount; } - public async Task> GetUserGroupMessagesAsync(Guid sendUserId, long groupId, string filter = "", - string sorting = nameof(UserMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10) + public virtual async Task> GetUserGroupMessagesAsync( + Guid sendUserId, + long groupId, + string filter = "", + string sorting = nameof(UserMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default) { + sorting = reverse ? sorting + " desc" : sorting; var groupMessages = await DbContext.Set() .Distinct() .Where(x => x.GroupId.Equals(groupId) && x.CreatorId.Equals(sendUserId)) .WhereIf(type != null, x => x.Type.Equals(type)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) .OrderBy(sorting ?? nameof(GroupMessage.MessageId)) - .Page(skipCount, maxResultCount) + .PageBy(skipCount, maxResultCount) .AsNoTracking() - .ToListAsync(); + .ToListAsync(GetCancellationToken(cancellationToken)); return groupMessages; } - public async Task GetUserGroupMessagesCountAsync(Guid sendUserId, long groupId, string filter = "", MessageType? type = null) + public virtual async Task GetUserGroupMessagesCountAsync( + Guid sendUserId, + long groupId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default) { var groupMessagesCount = await DbContext.Set() - .Distinct() .Where(x => x.GroupId.Equals(groupId) && x.CreatorId.Equals(sendUserId)) .WhereIf(type != null, x => x.Type.Equals(type)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) - .LongCountAsync(); + .LongCountAsync(GetCancellationToken(cancellationToken)); return groupMessagesCount; } - public async Task GetUserMessageAsync(long id) + public virtual async Task GetCountAsync( + long groupId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default) + { + return await DbContext.Set() + .Where(x => x.GroupId.Equals(groupId)) + .WhereIf(type != null, x => x.Type.Equals(type)) + .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetCountAsync( + Guid sendUserId, + Guid receiveUserId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default) + { + return await DbContext.Set() + .Where(x => x.ReceiveUserId.Equals(receiveUserId) && x.CreatorId.Equals(sendUserId)) + .WhereIf(type != null, x => x.Type.Equals(type)) + .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetUserMessageAsync( + long id, + CancellationToken cancellationToken = default) { return await DbContext.Set() .Where(x => x.MessageId.Equals(id)) .AsNoTracking() - .FirstOrDefaultAsync(); + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); } - public async Task> GetUserMessagesAsync(Guid sendUserId, Guid receiveUserId, string filter = "", - string sorting = nameof(UserMessage.MessageId), MessageType? type = null, int skipCount = 1, int maxResultCount = 10) + public virtual async Task> GetUserMessagesAsync( + Guid sendUserId, + Guid receiveUserId, + string filter = "", + string sorting = nameof(UserMessage.MessageId), + bool reverse = true, + MessageType? type = null, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default) { + sorting = reverse ? sorting + " desc" : sorting; var userMessages = await DbContext.Set() .Distinct() .Where(x => x.CreatorId.Equals(sendUserId) && x.ReceiveUserId.Equals(receiveUserId)) @@ -102,45 +168,42 @@ namespace LINGYUN.Abp.MessageService.Chat .OrderBy(sorting ?? nameof(GroupMessage.MessageId)) .Page(skipCount, maxResultCount) .AsNoTracking() - .ToListAsync(); + .ToListAsync(GetCancellationToken(cancellationToken)); return userMessages; } - public async Task GetUserMessagesCountAsync(Guid sendUserId, Guid receiveUserId, string filter = "", MessageType? type = null) + public virtual async Task GetUserMessagesCountAsync( + Guid sendUserId, + Guid receiveUserId, + string filter = "", + MessageType? type = null, + CancellationToken cancellationToken = default) { var userMessagesCount = await DbContext.Set() .Distinct() .Where(x => x.CreatorId.Equals(sendUserId) && x.ReceiveUserId.Equals(receiveUserId)) .WhereIf(type != null, x => x.Type.Equals(type)) .WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Content.Contains(filter) || x.SendUserName.Contains(filter)) - .LongCountAsync(); + .LongCountAsync(GetCancellationToken(cancellationToken)); return userMessagesCount; } - public async Task InsertGroupMessageAsync(GroupMessage groupMessage, bool saveChangs = false) + public virtual async Task InsertGroupMessageAsync( + GroupMessage groupMessage, + CancellationToken cancellationToken = default) { - groupMessage = (await DbContext.Set().AddAsync(groupMessage, GetCancellationToken())).Entity; - - if(saveChangs) - { - await DbContext.SaveChangesAsync(); - } - - return groupMessage; + await DbContext.Set() + .AddAsync(groupMessage, GetCancellationToken(cancellationToken)); } - public async Task InsertUserMessageAsync(UserMessage userMessage, bool saveChangs = false) + public virtual async Task InsertUserMessageAsync( + UserMessage userMessage, + CancellationToken cancellationToken = default) { - userMessage = (await DbContext.Set().AddAsync(userMessage, GetCancellationToken())).Entity; - - if (saveChangs) - { - await DbContext.SaveChangesAsync(); - } - - return userMessage; + await DbContext.Set() + .AddAsync(userMessage, GetCancellationToken(cancellationToken)); } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatCardRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatCardRepository.cs new file mode 100644 index 000000000..ff63e0edd --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatCardRepository.cs @@ -0,0 +1,63 @@ +using LINGYUN.Abp.IM; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class EfCoreUserChatCardRepository : EfCoreRepository, IUserChatCardRepository + { + public EfCoreUserChatCardRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public virtual async Task CheckUserIdExistsAsync(Guid userId, CancellationToken cancellationToken = default) + { + return await DbSet + .AnyAsync(ucc => ucc.UserId == userId, + GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetMemberAsync(Guid findUserId, CancellationToken cancellationToken = default) + { + return await DbSet + .Where(ucc => ucc.UserId == findUserId) + .Select(ucc => ucc.ToUserCard()) + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetMemberCountAsync(string findUserName = "", int? startAge = null, int? endAge = null, Sex? sex = null, CancellationToken cancellationToken = default) + { + return await DbSet + .WhereIf(!findUserName.IsNullOrWhiteSpace(), ucc => ucc.UserName.Contains(findUserName)) + .WhereIf(startAge.HasValue, ucc => ucc.Age >= startAge.Value) + .WhereIf(endAge.HasValue, ucc => ucc.Age <= endAge.Value) + .WhereIf(sex.HasValue, ucc => ucc.Sex == sex) + .CountAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetMembersAsync(string findUserName = "", int? startAge = null, int? endAge = null, Sex? sex = null, string sorting = nameof(UserChatCard.UserId), bool reverse = false, int skipCount = 0, int maxResultCount = 10, CancellationToken cancellationToken = default) + { + sorting ??= nameof(UserChatCard.UserId); + sorting = reverse ? sorting + " desc" : sorting; + return await DbSet + .WhereIf(!findUserName.IsNullOrWhiteSpace(), ucc => ucc.UserName.Contains(findUserName)) + .WhereIf(startAge.HasValue, ucc => ucc.Age >= startAge.Value) + .WhereIf(endAge.HasValue, ucc => ucc.Age <= endAge.Value) + .WhereIf(sex.HasValue, ucc => ucc.Sex == sex) + .OrderBy(sorting) + .PageBy(skipCount, maxResultCount) + .Select(ucc => ucc.ToUserCard()) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatFriendRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatFriendRepository.cs new file mode 100644 index 000000000..a656d9977 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatFriendRepository.cs @@ -0,0 +1,164 @@ +using LINGYUN.Abp.IM.Contract; +using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class EfCoreUserChatFriendRepository : EfCoreRepository, IUserChatFriendRepository + { + public EfCoreUserChatFriendRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public virtual async Task FindByUserFriendIdAsync(Guid userId, Guid friendId, CancellationToken cancellationToken = default) + { + return await DbSet + .Where(ucf => ucf.UserId == userId && ucf.FrientId == friendId) + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetMemberAsync(Guid userId, Guid friendId, CancellationToken cancellationToken = default) + { + var userFriendQuery = from ucf in DbContext.Set() + join ucc in DbContext.Set() + on ucf.FrientId equals ucc.UserId + where ucf.UserId == userId && ucf.FrientId == friendId + select new UserFriend + { + Age = ucc.Age, + AvatarUrl = ucc.AvatarUrl, + Birthday = ucc.Birthday, + Black = ucf.Black, + Description = ucc.Description, + DontDisturb = ucf.DontDisturb, + FriendId = ucf.FrientId, + NickName = ucc.NickName, + RemarkName = ucf.RemarkName, + Sex = ucc.Sex, + Sign = ucc.Sign, + SpecialFocus = ucf.SpecialFocus, + TenantId = ucf.TenantId, + UserId = ucf.UserId, + UserName = ucc.UserName + }; + + return await userFriendQuery + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetMembersAsync(Guid userId, string filter = "", string sorting = nameof(UserChatFriend.UserId), bool reverse = false, int skipCount = 0, int maxResultCount = 10, CancellationToken cancellationToken = default) + { + // 过滤用户资料 + var userChatCardQuery = DbContext.Set() + .WhereIf(!filter.IsNullOrWhiteSpace(), ucc => ucc.UserName.Contains(filter) || ucc.NickName.Contains(filter)); + + // 过滤好友资料 + var userChatFriendQuery = DbContext.Set() + .WhereIf(!filter.IsNullOrWhiteSpace(), ucf => ucf.RemarkName.Contains(filter)); + + // 组合查询 + var userFriendQuery = from ucf in userChatFriendQuery + join ucc in userChatCardQuery // TODO: Need LEFT JOIN? + on ucf.FrientId equals ucc.UserId + where ucf.UserId == userId + select new UserFriend + { + Age = ucc.Age, + AvatarUrl = ucc.AvatarUrl, + Birthday = ucc.Birthday, + Black = ucf.Black, + Description = ucc.Description, + DontDisturb = ucf.DontDisturb, + FriendId = ucf.FrientId, + NickName = ucc.NickName, + RemarkName = ucf.RemarkName, + Sex = ucc.Sex, + Sign = ucc.Sign, + SpecialFocus = ucf.SpecialFocus, + TenantId = ucf.TenantId, + UserId = ucf.UserId, + UserName = ucc.UserName + }; + + return await userFriendQuery + .OrderBy(sorting) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetLastContactMembersAsync( + Guid userId, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default) + { + var userReceiveMsgQuery = DbContext.Set() + .Where(um => um.ReceiveUserId == userId); + + var userFriendQuery = from ucf in DbContext.Set() + join ucc in DbContext.Set() + on ucf.FrientId equals ucc.UserId + join um in userReceiveMsgQuery + on ucc.UserId equals um.CreatorId + where ucf.UserId == userId + orderby um.CreationTime descending // 消息创建时间倒序 + select new UserFriend + { + Age = ucc.Age, + AvatarUrl = ucc.AvatarUrl, + Birthday = ucc.Birthday, + Black = ucf.Black, + Description = ucc.Description, + DontDisturb = ucf.DontDisturb, + FriendId = ucf.FrientId, + NickName = ucc.NickName, + RemarkName = ucf.RemarkName, + Sex = ucc.Sex, + Sign = ucc.Sign, + SpecialFocus = ucf.SpecialFocus, + TenantId = ucf.TenantId, + UserId = ucf.UserId, + UserName = ucc.UserName + }; + + return await userFriendQuery + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetMembersCountAsync(Guid userId, string filter = "", CancellationToken cancellationToken = default) + { + var userChatCardQuery = DbContext.Set() + .WhereIf(!filter.IsNullOrWhiteSpace(), ucc => ucc.UserName.Contains(filter) || ucc.NickName.Contains(filter)); + + var userChatFriendQuery = DbContext.Set() + .WhereIf(!filter.IsNullOrWhiteSpace(), ucf => ucf.RemarkName.Contains(filter)); + + var userFriendQuery = from ucf in userChatFriendQuery + join ucc in userChatCardQuery + on ucf.FrientId equals ucc.UserId + where ucf.UserId == userId + select ucc; + + return await userFriendQuery + .CountAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task IsAddedAsync(Guid userId, Guid frientId, CancellationToken cancellationToken = default) + { + return await DbSet + .AnyAsync(ucf => ucf.UserId == userId && ucf.FrientId == frientId, + GetCancellationToken(cancellationToken)); + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatGroupRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatGroupRepository.cs index 388afa740..a234e3058 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatGroupRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatGroupRepository.cs @@ -1,11 +1,12 @@ using LINGYUN.Abp.IM.Group; using LINGYUN.Abp.MessageService.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; @@ -13,122 +14,292 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Chat { - public class EfCoreUserChatGroupRepository : EfCoreRepository, + public class EfCoreUserChatGroupRepository : EfCoreRepository, IUserChatGroupRepository, ITransientDependency { public EfCoreUserChatGroupRepository( - IDbContextProvider dbContextProvider) : base(dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } - public async Task> GetGroupUsersAsync(long groupId) + public virtual async Task GetMemberAsync( + long groupId, + Guid userId, + CancellationToken cancellationToken = default) { - // TODO: 急需单元测试,对这段代码不是太自信... - var groupUsers = await (from ug in DbSet - join x in ( - from gaj in DbContext.Set() - where gaj.GroupId.Equals(groupId) - select gaj - ) on ug.UserId equals x.UserId - into y from ga in y.DefaultIfEmpty() - where ug.GroupId.Equals(groupId) - select new UserGroup - { - GroupId = ug.GroupId, - IsSuperAdmin = ga != null && ga.IsSuperAdmin, - IsAdmin = ga != null, - TenantId = ug.TenantId, - UserId = ug.UserId - }) - .Distinct() - .AsNoTracking() - .ToListAsync(); - return groupUsers; - } + var cardQuery = from gp in DbContext.Set() + join ucg in DbContext.Set() + on gp.GroupId equals ucg.GroupId + join ugc in DbContext.Set() + on ucg.UserId equals ugc.UserId + join uc in DbContext.Set() + on ugc.UserId equals uc.UserId + where gp.GroupId == groupId && ugc.UserId == userId + select new GroupUserCard + { + TenantId = uc.TenantId, + UserId = uc.UserId, + UserName = uc.UserName, + Age = uc.Age, + AvatarUrl = uc.AvatarUrl, + IsAdmin = ugc.IsAdmin, + IsSuperAdmin = gp.AdminUserId == uc.UserId, + GroupId = gp.GroupId, + Birthday = uc.Birthday, + Description = uc.Description, + NickName = ugc.NickName ?? uc.NickName, + Sex = uc.Sex, + Sign = uc.Sign + }; - public async Task GetGroupUserCardAsync(long groupId, Guid userId) - { - var groupUserCard = await (from cg in DbContext.Set() - join ucg in DbContext.Set().DefaultIfEmpty() - on cg.GroupId equals ucg.GroupId - join cga in DbContext.Set().DefaultIfEmpty() - on cg.GroupId equals cga.GroupId - where ucg.GroupId.Equals(groupId) && cga.UserId.Equals(userId) - select new GroupUserCard - { - IsSuperAdmin = cga != null && cga.IsSuperAdmin, - IsAdmin = cga != null,//能查到数据就是管理员 - GroupId = ucg.GroupId, - UserId = ucg.UserId, - TenantId = ucg.TenantId, - Permissions = new Dictionary - { - { nameof(ChatGroupAdmin.AllowAddPeople), cga != null &&cga.AllowAddPeople }, - { nameof(ChatGroupAdmin.AllowDissolveGroup), cga != null &&cga.AllowDissolveGroup }, - { nameof(ChatGroupAdmin.AllowKickPeople), cga != null &&cga.AllowKickPeople }, - { nameof(ChatGroupAdmin.AllowSendNotice), cga != null &&cga.AllowSendNotice }, - { nameof(ChatGroupAdmin.AllowSilence), cga != null &&cga.AllowSilence }, - { nameof(ChatGroupAdmin.IsSuperAdmin), cga != null &&cga.IsSuperAdmin } - } - }) - .AsNoTracking() - .FirstOrDefaultAsync(); - - return groupUserCard; + return await cardQuery + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); } - public Task> GetGroupUsersAsync(long groupId, string filter = "", string sorting = "UserId", int skipCount = 1, int maxResultCount = 10) + public virtual async Task> GetMembersAsync( + long groupId, + string sorting = nameof(UserChatCard.UserId), + bool reverse = false, + int skipCount = 0, + int maxResultCount = 10, + CancellationToken cancellationToken = default) { - // TODO: 复杂的实现,暂时无关紧要,后期再说 :) - throw new NotImplementedException(); + sorting ??= nameof(UserChatCard.UserId); + sorting = reverse ? sorting + " desc" : sorting; + var cardQuery = from gp in DbContext.Set() + join ucg in DbContext.Set() + on gp.GroupId equals ucg.GroupId + join ugc in DbContext.Set() + on ucg.UserId equals ugc.UserId + join uc in DbContext.Set() + on ugc.UserId equals uc.UserId + where gp.GroupId == groupId + select new GroupUserCard + { + TenantId = uc.TenantId, + UserId = uc.UserId, + UserName = uc.UserName, + Age = uc.Age, + AvatarUrl = uc.AvatarUrl, + IsAdmin = ugc.IsAdmin, + IsSuperAdmin = gp.AdminUserId == uc.UserId, + GroupId = gp.GroupId, + Birthday = uc.Birthday, + Description = uc.Description, + NickName = ugc.NickName ?? uc.NickName, + Sex = uc.Sex, + Sign = uc.Sign + }; + + return await cardQuery + .OrderBy(sorting ?? nameof(UserChatCard.UserId)) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); } - public Task GetGroupUsersCountAsync(long groupId, string filter = "") + public virtual async Task GetMembersCountAsync( + long groupId, + CancellationToken cancellationToken = default) { - // TODO: 复杂的实现,暂时无关紧要,后期再说 :) - throw new NotImplementedException(); + var cardQuery = from gp in DbContext.Set() + join ucg in DbContext.Set() + on gp.GroupId equals ucg.GroupId + join ugc in DbContext.Set() + on ucg.UserId equals ugc.UserId + join uc in DbContext.Set() + on ugc.UserId equals uc.UserId + where gp.GroupId == groupId + select ucg; + + return await cardQuery + .CountAsync(GetCancellationToken(cancellationToken)); } - public async Task GetUserGroupAsync(long groupId, Guid userId) + public virtual async Task MemberHasInGroupAsync( + long groupId, + Guid userId, + CancellationToken cancellationToken = default) { - return await DbSet.Where(x => x.GroupId.Equals(groupId) && x.UserId.Equals(userId)) - .AsNoTracking() - .FirstOrDefaultAsync(); + return await DbContext.Set() + .AnyAsync(ucg => ucg.GroupId == groupId && ucg.UserId == userId, + GetCancellationToken(cancellationToken)); } - public async Task> GetUserGroupsAsync(Guid userId) + public virtual async Task> GetMemberGroupsAsync( + Guid userId, + CancellationToken cancellationToken = default) { - // TODO: 急需单元测试,对这段代码不是太自信... - var userGroups = await (from ucg in DbSet - join cg in DbContext.Set() - on ucg.GroupId equals cg.GroupId - group cg by new - { - cg.GroupId, - cg.Name, - cg.AllowAnonymous, - cg.AllowSendMessage, - cg.MaxUserCount - } - into ug - orderby ug.Key.GroupId descending - select new Group - { - AllowAnonymous = ug.Key.AllowAnonymous, - AllowSendMessage = ug.Key.AllowSendMessage, - GroupUserCount = ug.Count(), - MaxUserLength = ug.Key.MaxUserCount, - Name = ug.Key.Name - }) - .Distinct() - .ToListAsync(); - - return userGroups; + var groupQuery = from gp in DbContext.Set() + join ucg in DbContext.Set() + on gp.GroupId equals ucg.GroupId + where ucg.UserId.Equals(userId) + group ucg by new + { + gp.AllowAnonymous, + gp.AllowSendMessage, + gp.MaxUserCount, + gp.Name + } + into cg + select new Group + { + AllowAnonymous = cg.Key.AllowAnonymous, + AllowSendMessage = cg.Key.AllowSendMessage, + MaxUserLength = cg.Key.MaxUserCount, + Name = cg.Key.Name, + GroupUserCount = cg.Count() + }; + + return await groupQuery + .ToListAsync(GetCancellationToken(cancellationToken)); } - public async Task UserHasInGroupAsync(long groupId, Guid userId) + public virtual async Task RemoveMemberFormGroupAsync( + long groupId, + Guid userId, + CancellationToken cancellationToken = default) { - return await DbSet.AnyAsync(x => x.GroupId.Equals(groupId) && x.UserId.Equals(userId)); + await DeleteAsync(ucg => ucg.GroupId == groupId && ucg.UserId == userId); } + + //public virtual async Task> GetGroupUsersAsync( + // long groupId, + // CancellationToken cancellationToken = default) + //{ + // // TODO: 急需单元测试,对这段代码不是太自信... + // var groupUsers = await (from cg in DbContext.Set() + // join ucg in DbContext.Set() + // on cg.GroupId equals ucg.GroupId + // join ugc in DbContext.Set() + // on ucg.UserId equals ugc.UserId + // where cg.GroupId.Equals(groupId) + // select new GroupUserCard + // { + // GroupId = ucg.GroupId, + // IsSuperAdmin = ugc.UserId == cg.AdminUserId, + // IsAdmin = ugc.IsAdmin, + // TenantId = ucg.TenantId, + // UserId = ucg.UserId + // }) + // .Distinct() + // .AsNoTracking() + // .ToListAsync(GetCancellationToken(cancellationToken)); + // return groupUsers; + //} + + //public virtual async Task GetMemberAsync( + // long groupId, + // Guid userId, + // CancellationToken cancellationToken = default) + //{ + // var groupUserCard = await (from cg in DbContext.Set() + // join ucg in DbContext.Set().DefaultIfEmpty() + // on cg.GroupId equals ucg.GroupId + // join ucc in DbContext.Set().DefaultIfEmpty() + // on ucg.UserId equals ucc.UserId + // join cga in DbContext.Set().DefaultIfEmpty() + // on cg.GroupId equals cga.GroupId + // where ucg.GroupId.Equals(groupId) && cga.UserId.Equals(userId) + // select new GroupUserCard + // { + // IsSuperAdmin = cga != null && cga.IsSuperAdmin, + // IsAdmin = cga != null,//能查到数据就是管理员 + // GroupId = ucg.GroupId, + // UserId = ucg.UserId, + // TenantId = ucg.TenantId, + // Permissions = new Dictionary + // { + // { nameof(ChatGroupAdmin.AllowAddPeople), cga != null && cga.AllowAddPeople }, + // { nameof(ChatGroupAdmin.AllowDissolveGroup), cga != null && cga.AllowDissolveGroup }, + // { nameof(ChatGroupAdmin.AllowKickPeople), cga != null && cga.AllowKickPeople }, + // { nameof(ChatGroupAdmin.AllowSendNotice), cga != null && cga.AllowSendNotice }, + // { nameof(ChatGroupAdmin.AllowSilence), cga != null && cga.AllowSilence }, + // { nameof(ChatGroupAdmin.IsSuperAdmin), cga != null && cga.IsSuperAdmin } + // } + // }) + // .AsNoTracking() + // .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + + // return groupUserCard; + //} + + //public virtual Task> GetUsersAsync( + // long groupId, + // string filter = "", + // string sorting = nameof(UserGroup.UserId), + // bool reverse = false, + // int skipCount = 0, + // int maxResultCount = 10, + // CancellationToken cancellationToken = default) + //{ + // sorting = reverse ? sorting + " desc" : sorting; + // // TODO: 复杂的实现,暂时无关紧要,后期再说 :) + // throw new NotImplementedException(); + //} + + //public virtual Task GetMembersCountAsync( + // long groupId, + // string filter = "", + // CancellationToken cancellationToken = default) + //{ + // var ss = (from ucg in DbContext.Set() + // join cg in DbContext.Set() on ucg.GroupId equals cg.GroupId + // select cg) + // .WhereIf(!filter.IsNullOrWhiteSpace(),) + + // // TODO: 复杂的实现,暂时无关紧要,后期再说 :) + // //throw new NotImplementedException(); + //} + + //public virtual async Task GetUserGroupAsync( + // long groupId, + // Guid userId, + // CancellationToken cancellationToken = default) + //{ + // return await DbSet.Where(x => x.GroupId.Equals(groupId) && x.UserId.Equals(userId)) + // .AsNoTracking() + // .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + //} + + //public virtual async Task> GetUserGroupsAsync( + // Guid userId, + // CancellationToken cancellationToken = default) + //{ + // // TODO: 急需单元测试,对这段代码不是太自信... + // var userGroups = await (from ucg in DbSet + // join cg in DbContext.Set() + // on ucg.GroupId equals cg.GroupId + // group cg by new + // { + // cg.GroupId, + // cg.Name, + // cg.AllowAnonymous, + // cg.AllowSendMessage, + // cg.MaxUserCount + // } + // into ug + // orderby ug.Key.GroupId descending + // select new Group + // { + // AllowAnonymous = ug.Key.AllowAnonymous, + // AllowSendMessage = ug.Key.AllowSendMessage, + // GroupUserCount = ug.Count(), + // MaxUserLength = ug.Key.MaxUserCount, + // Name = ug.Key.Name + // }) + // .Distinct() + // .ToListAsync(GetCancellationToken(cancellationToken)); + + // return userGroups; + //} + + //public virtual async Task MemberHasInGroupAsync( + // long groupId, + // Guid userId, + // CancellationToken cancellationToken = default) + //{ + // return await DbSet + // .AnyAsync(x => x.GroupId.Equals(groupId) && x.UserId.Equals(userId), GetCancellationToken(cancellationToken)); + //} } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatSettingRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatSettingRepository.cs index 66e8926e3..d2784e0af 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatSettingRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreUserChatSettingRepository.cs @@ -9,11 +9,11 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Chat { - public class EfCoreUserChatSettingRepository : EfCoreRepository, + public class EfCoreUserChatSettingRepository : EfCoreRepository, IUserChatSettingRepository, ITransientDependency { public EfCoreUserChatSettingRepository( - IDbContextProvider dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/AbpMessageServiceEntityFrameworkCoreModule.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/AbpMessageServiceEntityFrameworkCoreModule.cs index f990d1ec0..2939391a7 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/AbpMessageServiceEntityFrameworkCoreModule.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/AbpMessageServiceEntityFrameworkCoreModule.cs @@ -22,8 +22,11 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore options.AddRepository(); options.AddRepository(); + options.AddRepository(); options.AddRepository(); + options.AddRepository(); + options.AddDefaultRepositories(includeAllEntities: true); }); } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/IMessageServiceDbContext.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/IMessageServiceDbContext.cs new file mode 100644 index 000000000..bbfc5d399 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/IMessageServiceDbContext.cs @@ -0,0 +1,14 @@ +using LINGYUN.Abp.MessageService.Chat; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace LINGYUN.Abp.MessageService.EntityFrameworkCore +{ + [ConnectionStringName(AbpMessageServiceDbProperties.ConnectionStringName)] + public interface IMessageServiceDbContext : IEfCoreDbContext + { + DbSet UserChatCards { get; set; } + DbSet UserGroupCards { get; set; } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContext.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContext.cs index 4f7fbb22d..893d3ba01 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContext.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContext.cs @@ -1,17 +1,20 @@ -using Microsoft.EntityFrameworkCore; +using LINGYUN.Abp.MessageService.Chat; +using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.EntityFrameworkCore { - [ConnectionStringName("MessageService")] - public class MessageServiceDbContext : AbpDbContext + [ConnectionStringName(AbpMessageServiceDbProperties.ConnectionStringName)] + public class MessageServiceDbContext : AbpDbContext, IMessageServiceDbContext { + public DbSet UserChatCards { get; set; } + public DbSet UserGroupCards { get; set; } + public MessageServiceDbContext(DbContextOptions options) : base(options) { } - protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ConfigureMessageService(options => diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs index e4f08a537..c3307fff8 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/EntityFrameworkCore/MessageServiceDbContextModelCreatingExtensions.cs @@ -89,6 +89,45 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore b.HasIndex(p => new { p.TenantId, p.GroupId }); }); + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "UserChatFriends", options.Schema); + + b.Property(p => p.RemarkName).HasMaxLength(UserChatCardConsts.MaxUserNameLength); + + b.ConfigureByConvention(); + + b.HasIndex(p => new { p.TenantId, p.UserId, p.FrientId }); + }); + + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "UserChatCards", options.Schema); + + b.Property(p => p.UserName).HasMaxLength(UserChatCardConsts.MaxUserNameLength).IsRequired(); + + b.Property(p => p.AvatarUrl).HasMaxLength(UserChatCardConsts.MaxAvatarUrlLength); + b.Property(p => p.Description).HasMaxLength(UserChatCardConsts.MaxDescriptionLength); + b.Property(p => p.NickName).HasMaxLength(UserChatCardConsts.MaxNickNameLength); + b.Property(p => p.Sign).HasMaxLength(UserChatCardConsts.MaxSignLength); + + b.ConfigureByConvention(); + + b.HasIndex(p => new { p.TenantId, p.UserId }); + }); + + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "UserGroupCards", options.Schema); + + b.Property(p => p.NickName).HasMaxLength(UserChatCardConsts.MaxNickNameLength); + + b.ConfigureByConvention(); + + b.HasIndex(p => new { p.TenantId, p.UserId }); + }); + + builder.Entity(b => { b.ToTable(options.TablePrefix + "UserChatSettings", options.Schema); @@ -125,15 +164,6 @@ namespace LINGYUN.Abp.MessageService.EntityFrameworkCore b.HasIndex(p => new { p.TenantId, p.GroupId }); }); - builder.Entity(b => - { - b.ToTable(options.TablePrefix + "ChatGroupAdmins", options.Schema); - - b.ConfigureMultiTenant(); - - b.HasIndex(p => new { p.TenantId, p.GroupId }); - }); - builder.Entity(b => { b.ToTable(options.TablePrefix + "ChatGroups", options.Schema); diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreNotificationRepository.cs index c4f698b56..97b094126 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreNotificationRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreNotificationRepository.cs @@ -9,11 +9,11 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Notifications { - public class EfCoreNotificationRepository : EfCoreRepository, + public class EfCoreNotificationRepository : EfCoreRepository, INotificationRepository, ITransientDependency { public EfCoreNotificationRepository( - IDbContextProvider dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs index 3fae6b5c1..1ae397e76 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs @@ -12,11 +12,11 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Notifications { - public class EfCoreUserNotificationRepository : EfCoreRepository, + public class EfCoreUserNotificationRepository : EfCoreRepository, IUserNotificationRepository, ITransientDependency { public EfCoreUserNotificationRepository( - IDbContextProvider dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs index ad73dfacd..622a053ec 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Subscriptions/EfCoreUserSubscribeRepository.cs @@ -11,11 +11,11 @@ using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.MessageService.Subscriptions { - public class EfCoreUserSubscribeRepository : EfCoreRepository, + public class EfCoreUserSubscribeRepository : EfCoreRepository, IUserSubscribeRepository, ITransientDependency { public EfCoreUserSubscribeRepository( - IDbContextProvider dbContextProvider) + IDbContextProvider dbContextProvider) : base(dbContextProvider) { } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/ChatController.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/ChatController.cs index 806a68968..374b8631a 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/ChatController.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/ChatController.cs @@ -9,7 +9,7 @@ using Volo.Abp.AspNetCore.Mvc; namespace LINGYUN.Abp.MessageService.Chat { [RemoteService(Name = AbpMessageServiceConsts.RemoteServiceName)] - [Route("api/chat")] + [Route("api/im/chat")] public class ChatController : AbpController, IChatAppService { private readonly IChatAppService _chatAppService; @@ -35,7 +35,7 @@ namespace LINGYUN.Abp.MessageService.Chat [HttpGet] [Route("groups/users")] - public virtual async Task> GetGroupUsersAsync(GroupUserGetByPagedDto groupUserGetByPaged) + public virtual async Task> GetGroupUsersAsync(GroupUserGetByPagedDto groupUserGetByPaged) { return await _chatAppService.GetGroupUsersAsync(groupUserGetByPaged); } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/MyFriendController.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/MyFriendController.cs new file mode 100644 index 000000000..fafcf3531 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Chat/MyFriendController.cs @@ -0,0 +1,46 @@ +using LINGYUN.Abp.IM.Contract; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc; + +namespace LINGYUN.Abp.MessageService.Chat +{ + [RemoteService(Name = AbpMessageServiceConsts.RemoteServiceName)] + [Route("api/im/my-friends")] + public class MyFriendController : AbpController, IMyFriendAppService + { + protected IMyFriendAppService MyFriendAppService { get; } + + public MyFriendController(IMyFriendAppService myFriendAppService) + { + MyFriendAppService = myFriendAppService; + } + + [HttpPost] + public virtual async Task CreateAsync(MyFriendCreateDto input) + { + await MyFriendAppService.CreateAsync(input); + } + + [HttpDelete] + public virtual async Task DeleteAsync(MyFriendOperationDto input) + { + await MyFriendAppService.DeleteAsync(input); + } + + [HttpGet] + [Route("last-contacts")] + public virtual async Task> GetLastContactFriendsAsync(PagedResultRequestDto input) + { + return await MyFriendAppService.GetLastContactFriendsAsync(input); + } + + [HttpGet] + public virtual async Task> GetMyFriendsAsync(MyFriendGetByPagedDto input) + { + return await MyFriendAppService.GetMyFriendsAsync(input); + } + } +} diff --git a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs index dbbb331e1..2f1bed9d9 100644 --- a/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs +++ b/aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/BackendAdminHostModule.cs @@ -36,6 +36,7 @@ using Volo.Abp.Autofac; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.Data; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.FeatureManagement; @@ -181,6 +182,11 @@ namespace LINGYUN.Abp.BackendAdmin options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); }); + Configure(options => + { + options.AutoEventSelectors.AddNamespace("Volo.Abp.TenantManagement"); + }); + Configure(options => { var redisConfig = ConfigurationOptions.Parse(options.Configuration); diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db index f3d218787..99db5d637 100644 Binary files a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db and b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db differ diff --git a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs index eceaa69b1..d97700826 100644 --- a/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs +++ b/aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host/AbpIdentityServerAdminHttpApiHostModule.cs @@ -30,6 +30,7 @@ using Volo.Abp.Authorization.Permissions; using Volo.Abp.Autofac; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.Identity.Localization; @@ -174,6 +175,12 @@ namespace LINGYUN.Abp.IdentityServer4 options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); }); + Configure(options => + { + options.AutoEventSelectors.AddNamespace("Volo.Abp.Identity"); + options.AutoEventSelectors.AddNamespace("Volo.Abp.IdentityServer"); + }); + Configure(options => { var redisConfig = ConfigurationOptions.Parse(options.Configuration); diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024093309_Add-MemberCard-Entity.Designer.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024093309_Add-MemberCard-Entity.Designer.cs new file mode 100644 index 000000000..e2720f3da --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024093309_Add-MemberCard-Entity.Designer.cs @@ -0,0 +1,590 @@ +// +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("20201024093309_Add-MemberCard-Entity")] + partial class AddMemberCardEntity + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) + .HasAnnotation("ProductVersion", "3.1.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.ChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Address") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("AdminUserId") + .HasColumnType("char(36)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("MaxUserCount") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(20) CHARACTER SET utf8mb4") + .HasMaxLength(20); + + b.Property("Notice") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("Tag") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AppChatGroups"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.GroupChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.GroupMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("SendState") + .HasColumnType("tinyint"); + + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupMessages"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("AvatarUrl") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Birthday") + .HasColumnType("datetime(6)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("NickName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("Sex") + .HasColumnType("int"); + + b.Property("Sign") + .HasColumnType("varchar(30) CHARACTER SET utf8mb4") + .HasMaxLength(30); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatCards"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId", "UserId"); + + b.ToTable("AppUserChatGroups"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AllowAddFriend") + .HasColumnType("tinyint(1)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowReceiveMessage") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("RequireAddFriendValition") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatSettings"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserGroupCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("IsAdmin") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("NickName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("SilenceEnd") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserGroupCards"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("ReceiveUserId") + .HasColumnType("char(36)"); + + b.Property("SendState") + .HasColumnType("tinyint"); + + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ReceiveUserId"); + + b.ToTable("AppUserMessages"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserSpecialFocus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("FocusUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserSpecialFocuss"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime(6)"); + + b.Property("NotificationCateGory") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("NotificationData") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("NotificationName") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("NotificationTypeName") + .IsRequired() + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Severity") + .HasColumnType("tinyint"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "NotificationName"); + + b.ToTable("AppNotifications"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("ReadStatus") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationId") + .HasName("IX_Tenant_User_Notification_Id"); + + b.ToTable("AppUserNotifications"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("NotificationName") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128) + .HasDefaultValue("/"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationName") + .IsUnique() + .HasName("IX_Tenant_User_Notification_Name"); + + b.ToTable("AppUserSubscribes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024093309_Add-MemberCard-Entity.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024093309_Add-MemberCard-Entity.cs new file mode 100644 index 000000000..4e6bdc925 --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024093309_Add-MemberCard-Entity.cs @@ -0,0 +1,125 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace LINGYUN.Abp.MessageService.Migrations +{ + public partial class AddMemberCardEntity : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AppChatGroupAdmins"); + + migrationBuilder.AddColumn( + name: "AdminUserId", + table: "AppChatGroups", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); + + migrationBuilder.CreateTable( + name: "AppUserChatCards", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ExtraProperties = table.Column(nullable: true), + ConcurrencyStamp = table.Column(maxLength: 40, nullable: true), + CreationTime = table.Column(nullable: false), + CreatorId = table.Column(nullable: true), + LastModificationTime = table.Column(nullable: true), + LastModifierId = table.Column(nullable: true), + TenantId = table.Column(nullable: true), + UserId = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: false), + Sex = table.Column(nullable: false), + Sign = table.Column(maxLength: 30, nullable: true), + NickName = table.Column(maxLength: 256, nullable: true), + Description = table.Column(maxLength: 50, nullable: true), + AvatarUrl = table.Column(maxLength: 512, nullable: true), + Birthday = table.Column(nullable: true), + Age = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AppUserChatCards", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AppUserGroupCards", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ExtraProperties = table.Column(nullable: true), + ConcurrencyStamp = table.Column(maxLength: 40, nullable: true), + CreationTime = table.Column(nullable: false), + CreatorId = table.Column(nullable: true), + LastModificationTime = table.Column(nullable: true), + LastModifierId = table.Column(nullable: true), + TenantId = table.Column(nullable: true), + UserId = table.Column(nullable: false), + NickName = table.Column(maxLength: 256, nullable: true), + IsAdmin = table.Column(nullable: false), + SilenceEnd = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AppUserGroupCards", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_AppUserChatCards_TenantId_UserId", + table: "AppUserChatCards", + columns: new[] { "TenantId", "UserId" }); + + migrationBuilder.CreateIndex( + name: "IX_AppUserGroupCards_TenantId_UserId", + table: "AppUserGroupCards", + columns: new[] { "TenantId", "UserId" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AppUserChatCards"); + + migrationBuilder.DropTable( + name: "AppUserGroupCards"); + + migrationBuilder.DropColumn( + name: "AdminUserId", + table: "AppChatGroups"); + + migrationBuilder.CreateTable( + name: "AppChatGroupAdmins", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + AllowAddPeople = table.Column(type: "tinyint(1)", nullable: false), + AllowDissolveGroup = table.Column(type: "tinyint(1)", nullable: false), + AllowKickPeople = table.Column(type: "tinyint(1)", nullable: false), + AllowSendNotice = table.Column(type: "tinyint(1)", nullable: false), + AllowSilence = table.Column(type: "tinyint(1)", nullable: false), + CreationTime = table.Column(type: "datetime(6)", nullable: false), + CreatorId = table.Column(type: "char(36)", nullable: true), + GroupId = table.Column(type: "bigint", nullable: false), + IsSuperAdmin = table.Column(type: "tinyint(1)", nullable: false), + LastModificationTime = table.Column(type: "datetime(6)", nullable: true), + LastModifierId = table.Column(type: "char(36)", nullable: true), + TenantId = table.Column(type: "char(36)", nullable: true), + UserId = table.Column(type: "char(36)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AppChatGroupAdmins", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_AppChatGroupAdmins_TenantId_GroupId", + table: "AppChatGroupAdmins", + columns: new[] { "TenantId", "GroupId" }); + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024114206_Add-UserChatFriend-Entity.Designer.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024114206_Add-UserChatFriend-Entity.Designer.cs new file mode 100644 index 000000000..56da787fa --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024114206_Add-UserChatFriend-Entity.Designer.cs @@ -0,0 +1,634 @@ +// +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("20201024114206_Add-UserChatFriend-Entity")] + partial class AddUserChatFriendEntity + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) + .HasAnnotation("ProductVersion", "3.1.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.ChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Address") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("AdminUserId") + .HasColumnType("char(36)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("MaxUserCount") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(20) CHARACTER SET utf8mb4") + .HasMaxLength(20); + + b.Property("Notice") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("Tag") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AppChatGroups"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.GroupChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.GroupMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("SendState") + .HasColumnType("tinyint"); + + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupMessages"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatBlack", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("ShieldUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("AvatarUrl") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Birthday") + .HasColumnType("datetime(6)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("NickName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("Sex") + .HasColumnType("int"); + + b.Property("Sign") + .HasColumnType("varchar(30) CHARACTER SET utf8mb4") + .HasMaxLength(30); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatCards"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Black") + .HasColumnType("tinyint(1)"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("DontDisturb") + .HasColumnType("tinyint(1)"); + + b.Property("FrientId") + .HasColumnType("char(36)"); + + b.Property("RemarkName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("SpecialFocus") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "FrientId"); + + b.ToTable("AppUserChatFriends"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId", "UserId"); + + b.ToTable("AppUserChatGroups"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AllowAddFriend") + .HasColumnType("tinyint(1)"); + + b.Property("AllowAnonymous") + .HasColumnType("tinyint(1)"); + + b.Property("AllowReceiveMessage") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSendMessage") + .HasColumnType("tinyint(1)"); + + b.Property("RequireAddFriendValition") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserChatSettings"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserGroupCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("IsAdmin") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("NickName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("SilenceEnd") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserGroupCards"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("MessageId") + .HasColumnType("bigint"); + + b.Property("ReceiveUserId") + .HasColumnType("char(36)"); + + b.Property("SendState") + .HasColumnType("tinyint"); + + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ReceiveUserId"); + + b.ToTable("AppUserMessages"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserSpecialFocus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("char(36)"); + + b.Property("FocusUserId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserSpecialFocuss"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime(6)"); + + b.Property("NotificationCateGory") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("NotificationData") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("NotificationName") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("NotificationTypeName") + .IsRequired() + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Severity") + .HasColumnType("tinyint"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "NotificationName"); + + b.ToTable("AppNotifications"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Notifications.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("NotificationId") + .HasColumnType("bigint"); + + b.Property("ReadStatus") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationId") + .HasName("IX_Tenant_User_Notification_Id"); + + b.ToTable("AppUserNotifications"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Subscriptions.UserSubscribe", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("NotificationName") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128) + .HasDefaultValue("/"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId", "NotificationName") + .IsUnique() + .HasName("IX_Tenant_User_Notification_Name"); + + b.ToTable("AppUserSubscribes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024114206_Add-UserChatFriend-Entity.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024114206_Add-UserChatFriend-Entity.cs new file mode 100644 index 000000000..183413ae4 --- /dev/null +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/20201024114206_Add-UserChatFriend-Entity.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace LINGYUN.Abp.MessageService.Migrations +{ + public partial class AddUserChatFriendEntity : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AppUserChatFriends", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreationTime = table.Column(nullable: false), + CreatorId = table.Column(nullable: true), + TenantId = table.Column(nullable: true), + UserId = table.Column(nullable: false), + FrientId = table.Column(nullable: false), + Black = table.Column(nullable: false), + DontDisturb = table.Column(nullable: false), + SpecialFocus = table.Column(nullable: false), + RemarkName = table.Column(maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AppUserChatFriends", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_AppUserChatFriends_TenantId_UserId_FrientId", + table: "AppUserChatFriends", + columns: new[] { "TenantId", "UserId", "FrientId" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AppUserChatFriends"); + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs index 1cfe6b4a1..8082abdb1 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Migrations/MessageServiceHostMigrationsDbContextModelSnapshot.cs @@ -16,10 +16,10 @@ namespace LINGYUN.Abp.MessageService.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) - .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("ProductVersion", "3.1.7") .HasAnnotation("Relational:MaxIdentifierLength", 64); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroup", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.ChatGroup", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -29,6 +29,9 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnType("varchar(256) CHARACTER SET utf8mb4") .HasMaxLength(256); + b.Property("AdminUserId") + .HasColumnType("char(36)"); + b.Property("AllowAnonymous") .HasColumnType("tinyint(1)"); @@ -39,7 +42,7 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnName("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") .HasColumnName("CreatorId") .HasColumnType("char(36)"); @@ -54,7 +57,7 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnName("LastModificationTime") .HasColumnType("datetime(6)"); - b.Property("LastModifierId") + b.Property("LastModifierId") .HasColumnName("LastModifierId") .HasColumnType("char(36)"); @@ -74,7 +77,7 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnType("varchar(512) CHARACTER SET utf8mb4") .HasMaxLength(512); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); @@ -85,61 +88,82 @@ namespace LINGYUN.Abp.MessageService.Migrations b.ToTable("AppChatGroups"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.ChatGroupAdmin", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.GroupChatBlack", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("bigint"); - b.Property("AllowAddPeople") - .HasColumnType("tinyint(1)"); + b.Property("CreationTime") + .HasColumnType("datetime(6)"); - b.Property("AllowDissolveGroup") - .HasColumnType("tinyint(1)"); + b.Property("CreatorId") + .HasColumnType("char(36)"); - b.Property("AllowKickPeople") - .HasColumnType("tinyint(1)"); + b.Property("GroupId") + .HasColumnType("bigint"); - b.Property("AllowSendNotice") - .HasColumnType("tinyint(1)"); + b.Property("ShieldUserId") + .HasColumnType("char(36)"); - b.Property("AllowSilence") - .HasColumnType("tinyint(1)"); + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "GroupId"); + + b.ToTable("AppGroupChatBlacks"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.GroupMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(1048576); b.Property("CreationTime") + .HasColumnName("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") .HasColumnType("char(36)"); b.Property("GroupId") .HasColumnType("bigint"); - b.Property("IsSuperAdmin") - .HasColumnType("tinyint(1)"); + b.Property("MessageId") + .HasColumnType("bigint"); - b.Property("LastModificationTime") - .HasColumnType("datetime(6)"); + b.Property("SendState") + .HasColumnType("tinyint"); - b.Property("LastModifierId") - .HasColumnType("char(36)"); + b.Property("SendUserName") + .IsRequired() + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() - .HasColumnType("char(36)"); + b.Property("Type") + .HasColumnType("int"); b.HasKey("Id"); b.HasIndex("TenantId", "GroupId"); - b.ToTable("AppChatGroupAdmins"); + b.ToTable("AppGroupMessages"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupChatBlack", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatBlack", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -148,105 +172,147 @@ namespace LINGYUN.Abp.MessageService.Migrations b.Property("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") .HasColumnType("char(36)"); - b.Property("GroupId") - .HasColumnType("bigint"); - - b.Property("ShieldUserId") - .IsRequired() + b.Property("ShieldUserId") .HasColumnType("char(36)"); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); + b.Property("UserId") + .HasColumnType("char(36)"); + b.HasKey("Id"); - b.HasIndex("TenantId", "GroupId"); + b.HasIndex("TenantId", "UserId"); - b.ToTable("AppGroupChatBlacks"); + b.ToTable("AppUserChatBlacks"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.GroupMessage", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatCard", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("bigint"); - b.Property("Content") - .IsRequired() - .HasColumnType("longtext CHARACTER SET utf8mb4") - .HasMaxLength(1048576); + b.Property("Age") + .HasColumnType("int"); + + b.Property("AvatarUrl") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Birthday") + .HasColumnType("datetime(6)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); b.Property("CreationTime") .HasColumnName("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") + .HasColumnName("CreatorId") .HasColumnType("char(36)"); - b.Property("GroupId") - .HasColumnType("bigint"); + b.Property("Description") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); - b.Property("MessageId") - .HasColumnType("bigint"); + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); - b.Property("SendState") - .HasColumnType("tinyint"); + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); - b.Property("SendUserName") - .IsRequired() - .HasColumnType("varchar(64) CHARACTER SET utf8mb4") - .HasMaxLength(64); + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("NickName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("Sex") + .HasColumnType("int"); - b.Property("TenantId") + b.Property("Sign") + .HasColumnType("varchar(30) CHARACTER SET utf8mb4") + .HasMaxLength(30); + + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("Type") - .HasColumnType("int"); + b.Property("UserId") + .HasColumnType("char(36)"); + + b.Property("UserName") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); b.HasKey("Id"); - b.HasIndex("TenantId", "GroupId"); + b.HasIndex("TenantId", "UserId"); - b.ToTable("AppGroupMessages"); + b.ToTable("AppUserChatCards"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatBlack", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatFriend", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("bigint"); + b.Property("Black") + .HasColumnType("tinyint(1)"); + b.Property("CreationTime") + .HasColumnName("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") + .HasColumnName("CreatorId") .HasColumnType("char(36)"); - b.Property("ShieldUserId") - .IsRequired() + b.Property("DontDisturb") + .HasColumnType("tinyint(1)"); + + b.Property("FrientId") .HasColumnType("char(36)"); - b.Property("TenantId") + b.Property("RemarkName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("SpecialFocus") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("char(36)"); b.HasKey("Id"); - b.HasIndex("TenantId", "UserId"); + b.HasIndex("TenantId", "UserId", "FrientId"); - b.ToTable("AppUserChatBlacks"); + b.ToTable("AppUserChatFriends"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatGroup", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatGroup", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -256,19 +322,18 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnName("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") .HasColumnName("CreatorId") .HasColumnType("char(36)"); b.Property("GroupId") .HasColumnType("bigint"); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("char(36)"); b.HasKey("Id"); @@ -278,7 +343,7 @@ namespace LINGYUN.Abp.MessageService.Migrations b.ToTable("AppUserChatGroups"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserChatSetting", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserChatSetting", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -299,12 +364,11 @@ namespace LINGYUN.Abp.MessageService.Migrations b.Property("RequireAddFriendValition") .HasColumnType("tinyint(1)"); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("char(36)"); b.HasKey("Id"); @@ -314,7 +378,63 @@ namespace LINGYUN.Abp.MessageService.Migrations b.ToTable("AppUserChatSettings"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserMessage", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserGroupCard", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnName("ConcurrencyStamp") + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("CreationTime") + .HasColumnName("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnName("CreatorId") + .HasColumnType("char(36)"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("IsAdmin") + .HasColumnType("tinyint(1)"); + + b.Property("LastModificationTime") + .HasColumnName("LastModificationTime") + .HasColumnType("datetime(6)"); + + b.Property("LastModifierId") + .HasColumnName("LastModifierId") + .HasColumnType("char(36)"); + + b.Property("NickName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("SilenceEnd") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnName("TenantId") + .HasColumnType("char(36)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AppUserGroupCards"); + }); + + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserMessage", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -329,14 +449,13 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnName("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") .HasColumnType("char(36)"); b.Property("MessageId") .HasColumnType("bigint"); - b.Property("ReceiveUserId") - .IsRequired() + b.Property("ReceiveUserId") .HasColumnType("char(36)"); b.Property("SendState") @@ -347,7 +466,7 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnType("varchar(64) CHARACTER SET utf8mb4") .HasMaxLength(64); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); @@ -361,7 +480,7 @@ namespace LINGYUN.Abp.MessageService.Migrations b.ToTable("AppUserMessages"); }); - modelBuilder.Entity("LINGYUN.Abp.MessageService.Messages.UserSpecialFocus", b => + modelBuilder.Entity("LINGYUN.Abp.MessageService.Chat.UserSpecialFocus", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -370,19 +489,17 @@ namespace LINGYUN.Abp.MessageService.Migrations b.Property("CreationTime") .HasColumnType("datetime(6)"); - b.Property("CreatorId") + b.Property("CreatorId") .HasColumnType("char(36)"); - b.Property("FocusUserId") - .IsRequired() + b.Property("FocusUserId") .HasColumnType("char(36)"); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("char(36)"); b.HasKey("Id"); @@ -431,7 +548,7 @@ namespace LINGYUN.Abp.MessageService.Migrations b.Property("Severity") .HasColumnType("tinyint"); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); @@ -457,12 +574,11 @@ namespace LINGYUN.Abp.MessageService.Migrations b.Property("ReadStatus") .HasColumnType("int"); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("char(36)"); b.HasKey("Id"); @@ -488,12 +604,11 @@ namespace LINGYUN.Abp.MessageService.Migrations .HasColumnType("varchar(100) CHARACTER SET utf8mb4") .HasMaxLength(100); - b.Property("TenantId") + b.Property("TenantId") .HasColumnName("TenantId") .HasColumnType("char(36)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("char(36)"); b.Property("UserName") diff --git a/vueJs/package-lock.json b/vueJs/package-lock.json index be3cf43d6..a6c66486a 100644 --- a/vueJs/package-lock.json +++ b/vueJs/package-lock.json @@ -14595,6 +14595,14 @@ "integrity": "sha1-W4o6d2Xf4AEmHd6RVYnngvjJTR4=", "dev": true }, + "lemon-imui": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/lemon-imui/download/lemon-imui-1.0.4.tgz", + "integrity": "sha1-cq+I/hTHnTLv886bV97T1XoG5TI=", + "requires": { + "vue": "^2.6.10" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npm.taobao.org/leven/download/leven-3.1.0.tgz", diff --git a/vueJs/package.json b/vueJs/package.json index e5f50de33..2970d1cf1 100644 --- a/vueJs/package.json +++ b/vueJs/package.json @@ -31,6 +31,7 @@ "js-cookie": "^2.2.1", "jsonlint": "^1.6.3", "jszip": "^3.3.0", + "lemon-imui": "^1.0.4", "lodash": "^4.17.15", "morgan": "^1.10.0", "normalize.css": "^8.0.1", diff --git a/vueJs/src/api/instant-message.ts b/vueJs/src/api/instant-message.ts new file mode 100644 index 000000000..97aadafed --- /dev/null +++ b/vueJs/src/api/instant-message.ts @@ -0,0 +1,71 @@ +import ApiService from './serviceBase' +import { PagedResultDto, PagedAndSortedResultRequestDto, PagedResultRequestDto } from './types' + +const serviceUrl = process.env.VUE_APP_BASE_API + +export default class ImApiService { + public static getMyFriends(payload: MyFriendGetByPaged) { + let _url = 'api/im/my-friends' + _url += '?filter=' + payload.filter + _url += '&sorting=' + payload.sorting + _url += '&reverse=' + payload.reverse + _url += '&skipCount=' + payload.skipCount + _url += '&maxResultCount=' + payload.maxResultCount + return ApiService.Get>(_url, serviceUrl) + } +} + +export enum Sex +{ + Male, + Female, + Other +} + +export class UserCard { + tenantId?: string + userId = '' + userName = '' + avatarUrl = '' + nickName = '' + age = 0 + sex = Sex.Male + sign = '' + description = '' + birthday?: Date +} + +export class UserFriend extends UserCard { + friendId = '' + remarkName = '' + black = false + specialFocus = false + dontDisturb = false +} + +export class MyFriendGetByPaged extends PagedAndSortedResultRequestDto { + filter = '' + sorting = 'UserName' + skipCount = 0 + reverse = false +} + +export enum MessageType { + Text = 0, + Image = 10, + Link = 20, + Video = 30 +} + +export class ChatMessage { + tenantId?: string + groupId = '' + messageId = '' + formUserId = '' + formUserName = '' + toUserId = '' + content = '' + sendTime = new Date() + isAnonymous = false + messageType = MessageType.Text +} diff --git a/vueJs/src/components/InstantMessage/index.vue b/vueJs/src/components/InstantMessage/index.vue new file mode 100644 index 000000000..5f578350e --- /dev/null +++ b/vueJs/src/components/InstantMessage/index.vue @@ -0,0 +1,122 @@ + + + diff --git a/vueJs/src/main.ts b/vueJs/src/main.ts index 00e5e0d17..a59ee9adb 100644 --- a/vueJs/src/main.ts +++ b/vueJs/src/main.ts @@ -8,10 +8,12 @@ import SvgIcon from 'vue-svgicon' import uploader from 'vue-simple-uploader' import contextMenu from 'vue-contextmenujs' import VueEvents from '@/components/EventBus' +import LemonIMUI from 'lemon-imui' import '@/styles/element-variables.scss' import 'view-design/dist/styles/iview.css' import '@/styles/index.scss' +import 'lemon-imui/dist/index.css' import App from '@/App.vue' import store from '@/store' @@ -44,6 +46,7 @@ Vue.use(SvgIcon, { Vue.use(uploader) Vue.use(contextMenu) Vue.use(VueEvents) +Vue.use(LemonIMUI) // Register global directives Object.keys(directives).forEach(key => { diff --git a/vueJs/src/shims.d.ts b/vueJs/src/shims.d.ts index 03355ea3b..bbe4bd43b 100644 --- a/vueJs/src/shims.d.ts +++ b/vueJs/src/shims.d.ts @@ -31,3 +31,6 @@ declare module 'vue-simple-uploader' // TODO vue-contextmenujs declare module 'vue-contextmenujs' + +// TODO lemon-imui +declare module 'lemon-imui' diff --git a/vueJs/src/views/dashboard/admin/index.vue b/vueJs/src/views/dashboard/admin/index.vue index 0a13972b5..63a5102ce 100644 --- a/vueJs/src/views/dashboard/admin/index.vue +++ b/vueJs/src/views/dashboard/admin/index.vue @@ -1,21 +1,36 @@