diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatMessageService.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatMessageService.cs index 6d60e4c8..7bc72004 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatMessageService.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatMessageService.cs @@ -54,14 +54,14 @@ namespace Yi.Framework.ChatHub.Application.Services //领域调用,群主消息调用bbs领域 //如果钱钱不足,将自动断言 - await _localEventBus.PublishAsync(new MoneyChangeEventArgs { UserId = CurrentUser.Id.Value, Number = -1 },false); + await _localEventBus.PublishAsync(new MoneyChangeEventArgs { UserId = CurrentUser.Id.Value, Number = -1 }, false); var mesageContext = MessageContext.CreateAll(input.Content, CurrentUser.Id!.Value); UserRoleMenuQueryEventArgs userRoleMenuQuery = new UserRoleMenuQueryEventArgs(CurrentUser.Id!.Value); //调用用户领域事件,获取用户信息,第一个发送者用户信息,第二个为接收者用户信息 await _localEventBus.PublishAsync(userRoleMenuQuery, false); - mesageContext.SetUserInfo(userRoleMenuQuery.Result.First(),null); + mesageContext.SetUserInfo(userRoleMenuQuery.Result.First(), null); await _userMessageManager.SendMessageAsync(mesageContext); await _userMessageManager.CreateMessageStoreAsync(mesageContext); @@ -110,7 +110,21 @@ namespace Yi.Framework.ChatHub.Application.Services .Where(x => x.CreationTime >= DateTime.Now.AddDays(-30)) .OrderBy(x => x.CreationTime) .ToListAsync(); + + var output = entities.Adapt>(); + var userIds = output.GetUserIds(); + + UserRoleMenuQueryEventArgs userRoleMenuQuery = new UserRoleMenuQueryEventArgs(userIds.ToArray()); + + //调用用户领域事件,获取用户信息,第一个发送者用户信息,第二个为接收者用户信息 + await _localEventBus.PublishAsync(userRoleMenuQuery, false); + + + + //映射用户信息 + output.MapperUserInfo(userRoleMenuQuery.Result); + return output; } } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs index 7aea415b..a4f474bf 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatUserService.cs @@ -1,19 +1,39 @@ using Mapster; using Volo.Abp.Application.Services; +using Volo.Abp.EventBus.Local; using Yi.Framework.ChatHub.Domain.Managers; using Yi.Framework.ChatHub.Domain.Shared.Model; +using Yi.Framework.Rbac.Domain.Shared.Etos; namespace Yi.Framework.ChatHub.Application.Services { public class ChatUserService : ApplicationService { private UserMessageManager _messageManager; - public ChatUserService(UserMessageManager messageManager) { _messageManager = messageManager; } + private ILocalEventBus _localEventBus; + public ChatUserService(UserMessageManager messageManager, ILocalEventBus localEventBus) + { _messageManager = messageManager; _localEventBus = localEventBus; } public async Task> GetListAsync() { + //映射用户信息 var userList = await _messageManager.GetAllUserAsync(); + + var userIds = userList.Select(x => x.UserId).Distinct().ToList(); + UserRoleMenuQueryEventArgs userRoleMenuQuery = new UserRoleMenuQueryEventArgs(userIds.ToArray()); + + //调用用户领域事件,获取用户信息,第一个发送者用户信息,第二个为接收者用户信息 + await _localEventBus.PublishAsync(userRoleMenuQuery, false); + + var userInfoDic = userRoleMenuQuery.Result.ToDictionary(x => x.User.Id); var output = userList.Adapt>(); + + foreach (var chatUser in output) + { + var currentUserInfo = userInfoDic[chatUser.UserId]; + chatUser.UserName= currentUserInfo.User.UserName; + chatUser.UserIcon = currentUserInfo.User.Icon; + } return output; } } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs index 698e2d44..626c6dc3 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs @@ -21,7 +21,7 @@ namespace Yi.Framework.ChatHub.Domain.Shared.Model /// /// 用户头像 /// - public string UserIcon { get; set; } + public string? UserIcon { get; set; } } } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs index 30120a3f..c02469d5 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs @@ -9,8 +9,33 @@ using Yi.Framework.Rbac.Domain.Shared.Dtos; namespace Yi.Framework.ChatHub.Domain.Shared.Model { + + public static class MessageContextExtensions + { + public static List GetUserIds(this List context) + { + return context.Where(x => x.ReceiveId is not null).Select(x => x.ReceiveId!.Value).Union(context.Select(x => x.SendUserId)).ToList(); + } + public static List MapperUserInfo(this List messageContexts,List userRoleMenuDtos) + { + var userInfoDic = userRoleMenuDtos.ToDictionary(x => x.User.Id); + foreach (var context in messageContexts) + { + if (context.ReceiveId is not null) + { + context.ReceiveInfo = userInfoDic[context.ReceiveId.Value]; + } + context.SendUserInfo = userInfoDic[context.SendUserId]; + } + return messageContexts; + } + } public class MessageContext { + /// + /// 映射用户信息 + /// + public static MessageContext CreatePersonal(string content, Guid userId, Guid sendUserId) { return new MessageContext() { MessageType = MessageTypeEnum.Personal, Content = content, ReceiveId = userId, SendUserId = sendUserId }; diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs index e8abf3fb..d3bdccfb 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs @@ -271,7 +271,7 @@ namespace Yi.Framework.Rbac.Application.Services throw new UserFriendlyException("用户未登录"); } //此处优先从缓存中获取 - var output = await _userManager.Get(userId.Value); + var output = await _userManager.GetInfoAsync(userId.Value); return output; } @@ -290,7 +290,7 @@ namespace Yi.Framework.Rbac.Application.Services throw new AbpAuthorizationException("用户未登录"); } - var data = await _userRepository.GetUserAllInfoAsync(userId ?? Guid.Empty); + var data = await _userManager.GetInfoAsync(userId!.Value); var menus = data.Menus.ToList(); //为超级管理员直接给全部路由 diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/EventHandlers/UserInfoHandler.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/EventHandlers/UserInfoHandler.cs index f5e10032..12ee27e8 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/EventHandlers/UserInfoHandler.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/EventHandlers/UserInfoHandler.cs @@ -21,13 +21,8 @@ namespace Yi.Framework.Rbac.Domain.EventHandlers public async Task HandleEventAsync(UserRoleMenuQueryEventArgs eventData) { //数据库查询方式 - eventData.Result = new List(); - - //缓存查询方式 - foreach (var userId in eventData.UserIds) - { - eventData.Result.Add(await _userManager.Get(userId)); - } + var result = await _userManager.GetInfoListAsync(eventData.UserIds); + eventData.Result = result; } } } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs index 7c89e674..8a460e31 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs @@ -67,7 +67,7 @@ namespace Yi.Framework.Rbac.Domain.Managers public async Task GetTokenByUserIdAsync(Guid userId) { //获取用户信息 - var userInfo = await _repository.GetUserAllInfoAsync(userId); + var userInfo = await _userManager.GetInfoAsync(userId); //判断用户状态 if (userInfo.User.State == false) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs index 6dc14d3a..7c5edc0f 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/UserManager.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using Mapster; +using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -9,6 +10,7 @@ using Volo.Abp.Guids; using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.Rbac.Domain.Repositories; using Yi.Framework.Rbac.Domain.Shared.Caches; +using Yi.Framework.Rbac.Domain.Shared.Consts; using Yi.Framework.Rbac.Domain.Shared.Dtos; using Yi.Framework.Rbac.Domain.Shared.Options; using Yi.Framework.SqlSugarCore.Abstractions; @@ -91,41 +93,107 @@ namespace Yi.Framework.Rbac.Domain.Managers /// 查询用户信息,已缓存 /// /// - public async Task Get(Guid userId) + public async Task GetInfoAsync(Guid userId) { - //if (userId is null) - //{ - // throw new UserFriendlyException("用户未登录"); - //} - //此处优先从缓存中获取 - UserRoleMenuDto output = null; + var user = await _userRepository.GetUserAllInfoAsync(userId); + var output = await GetInfoByCacheAsync(user); + return output; + } - var cacheData = await _userCache.GetAsync(new UserInfoCacheKey(userId)); - if (cacheData is not null) + /// + /// 批量查询用户信息 + /// + /// + /// + public async Task> GetInfoListAsync(List userIds) + { + List output = new List(); + var users = await _userRepository.GetListUserAllInfoAsync(userIds); + foreach (var user in users) { - output = cacheData.Info; - } - else - { - var data = await _userRepository.GetUserAllInfoAsync(userId); - //系统用户数据被重置,老前端访问重新授权 - if (data is null) - { - throw new AbpAuthorizationException(); - } - data.Menus.Clear(); - - output = data; - - var tokenExpiresMinuteTime = LazyServiceProvider.GetRequiredService>().Value.ExpiresMinuteTime; - //将用户信息放入缓存,下次获取直接从缓存中获取即可,过期时间为token过期时间 - await _userCache.SetAsync(new UserInfoCacheKey(userId), new UserInfoCacheItem(data), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(tokenExpiresMinuteTime) }); + output.Add(await GetInfoByCacheAsync(user)); } return output; } + private async Task GetInfoByCacheAsync(UserEntity user) + { + //此处优先从缓存中获取 + UserRoleMenuDto output = null; + var tokenExpiresMinuteTime = LazyServiceProvider.GetRequiredService>().Value.ExpiresMinuteTime; + var cacheData = await _userCache.GetOrAddAsync(new UserInfoCacheKey(user.Id), + async () => + { + var data = EntityMapToDto(user); + //系统用户数据被重置,老前端访问重新授权 + if (data is null) + { + throw new AbpAuthorizationException(); + } + data.Menus.Clear(); + output = data; + return new UserInfoCacheItem(data); + }, + () => new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(tokenExpiresMinuteTime) }); + if (cacheData is not null) + { + output = cacheData.Info; + } + return output!; + } + private UserRoleMenuDto EntityMapToDto(UserEntity user) + { + + var userRoleMenu = new UserRoleMenuDto(); + //首先获取到该用户全部信息,导航到角色、菜单,(菜单需要去重,完全交给Set来处理即可) + //if (user is null) + //{ + // throw new UserFriendlyException($"数据错误,用户id:{nameof(userId)} 不存在,请重新登录"); + //} + user.Password = string.Empty; + user.Salt = string.Empty; + + //超级管理员特殊处理 + if (UserConst.Admin.Equals(user.UserName)) + { + userRoleMenu.User = user.Adapt(); + userRoleMenu.RoleCodes.Add(UserConst.AdminRolesCode); + userRoleMenu.PermissionCodes.Add(UserConst.AdminPermissionCode); + return userRoleMenu; + } + + //得到角色集合 + var roleList = user.Roles; + + //得到菜单集合 + foreach (var role in roleList) + { + userRoleMenu.RoleCodes.Add(role.RoleCode); + + if (role.Menus is not null) + { + foreach (var menu in role.Menus) + { + if (!string.IsNullOrEmpty(menu.PermissionCode)) + { + userRoleMenu.PermissionCodes.Add(menu.PermissionCode); + } + userRoleMenu.Menus.Add(menu.Adapt()); + } + } + + //刚好可以去除一下多余的导航属性 + role.Menus = new List(); + userRoleMenu.Roles.Add(role.Adapt()); + } + + user.Roles = new List(); + userRoleMenu.User = user.Adapt(); + userRoleMenu.Menus = userRoleMenu.Menus.OrderByDescending(x => x.OrderNum).ToHashSet(); + return userRoleMenu; + } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Repositories/IUserRepository.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Repositories/IUserRepository.cs index 18662ad3..d602e222 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Repositories/IUserRepository.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Repositories/IUserRepository.cs @@ -8,11 +8,17 @@ namespace Yi.Framework.Rbac.Domain.Repositories public interface IUserRepository : ISqlSugarRepository { /// - /// 获取当前登录用户的所有信息 + /// 获取用户的所有信息 /// /// /// - Task GetUserAllInfoAsync(Guid userId); + Task GetUserAllInfoAsync(Guid userId); + /// + /// 批量获取用户的所有信息 + /// + /// + /// + Task> GetListUserAllInfoAsync(List userIds); } } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/Repositories/UserRepository.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/Repositories/UserRepository.cs index 44279849..4dd6e5b1 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/Repositories/UserRepository.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/Repositories/UserRepository.cs @@ -15,6 +15,17 @@ namespace Yi.Framework.Rbac.SqlSugarCore.Repositories public UserRepository(ISugarDbContextProvider sugarDbContextProvider) : base(sugarDbContextProvider) { } + /// + /// 获取用户ids的全部信息 + /// + /// + /// + /// + public async Task> GetListUserAllInfoAsync(List userIds) + { + var users = await _DbQueryable.Where(x => userIds.Contains(x.Id)).Includes(u => u.Roles.Where(r => r.IsDeleted == false).ToList(), r => r.Menus.Where(m => m.IsDeleted == false).ToList()).ToListAsync(); + return users; + } /// @@ -23,59 +34,15 @@ namespace Yi.Framework.Rbac.SqlSugarCore.Repositories /// /// /// - public async Task GetUserAllInfoAsync(Guid userId) + public async Task GetUserAllInfoAsync(Guid userId) { - - var userRoleMenu = new UserRoleMenuDto(); - //首先获取到该用户全部信息,导航到角色、菜单,(菜单需要去重,完全交给Set来处理即可) - //得到用户 var user = await _DbQueryable.Includes(u => u.Roles.Where(r => r.IsDeleted == false).ToList(), r => r.Menus.Where(m => m.IsDeleted == false).ToList()).InSingleAsync(userId); - if (user is null) - { - throw new UserFriendlyException($"数据错误,用户id:{nameof(userId)} 不存在,请重新登录"); - } - user.Password = string.Empty; - user.Salt = string.Empty; - - //超级管理员特殊处理 - if (UserConst.Admin.Equals(user.UserName)) - { - userRoleMenu.User = user.Adapt(); - userRoleMenu.RoleCodes.Add(UserConst.AdminRolesCode); - userRoleMenu.PermissionCodes.Add(UserConst.AdminPermissionCode); - return userRoleMenu; - } - - //得到角色集合 - var roleList = user.Roles; - - //得到菜单集合 - foreach (var role in roleList) - { - userRoleMenu.RoleCodes.Add(role.RoleCode); - - if (role.Menus is not null) - { - foreach (var menu in role.Menus) - { - if (!string.IsNullOrEmpty(menu.PermissionCode)) - { - userRoleMenu.PermissionCodes.Add(menu.PermissionCode); - } - userRoleMenu.Menus.Add(menu.Adapt()); - } - } - - //刚好可以去除一下多余的导航属性 - role.Menus = new List(); - userRoleMenu.Roles.Add(role.Adapt()); - } - - user.Roles = new List(); - userRoleMenu.User = user.Adapt(); - userRoleMenu.Menus = userRoleMenu.Menus.OrderByDescending(x => x.OrderNum).ToHashSet(); - return userRoleMenu; + return user; } + + + + } }