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