diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/GroupMessageInputDto.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/GroupMessageInputDto.cs new file mode 100644 index 00000000..3231d7bb --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/GroupMessageInputDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.ChatHub.Application.Contracts.Dtos +{ + public class GroupMessageInputDto + { + /// + /// 消息内容 + /// + public string Content { get; set; } + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/PersonalMessageInputDto.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/PersonalMessageInputDto.cs new file mode 100644 index 00000000..860faccc --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/PersonalMessageInputDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.ChatHub.Application.Contracts.Dtos +{ + public class PersonalMessageInputDto + { + /// + /// 用户id + /// + public Guid UserId { get; set; } + + /// + /// 消息内容 + /// + public string Content { get; set; } + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj index 8df46007..0e4dce4a 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Yi.Framework.ChatHub.Application.Contracts.csproj @@ -1,4 +1,4 @@ - + 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 new file mode 100644 index 00000000..0bcddfe1 --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/ChatMessageService.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Application.Services; +using Yi.Framework.ChatHub.Application.Contracts.Dtos; +using Yi.Framework.ChatHub.Domain.Managers; +using Yi.Framework.ChatHub.Domain.Shared.Model; + +namespace Yi.Framework.ChatHub.Application.Services +{ + public class ChatMessageService : ApplicationService + { + private UserMessageManager _userMessageManager; + public ChatMessageService(UserMessageManager userMessageManager) { _userMessageManager = userMessageManager; } + /// + /// 发送个人消息 + /// + /// + [HttpPost("chat-message/personal")] + [Authorize] + public async Task SendPersonalMessageAsync(PersonalMessageInputDto input) + { + await _userMessageManager.SendMessageAsync(MessageContext.CreatePersonal(input.Content, input.UserId,CurrentUser.Id!.Value)); ; + } + + + /// + /// 发送群组消息 + /// + /// + [HttpPost("chat-message/group")] + [Authorize] + public async Task SendGroupMessageAsync(GroupMessageInputDto input) + { + await _userMessageManager.SendMessageAsync(MessageContext.CreateAll(input.Content, CurrentUser.Id!.Value)); ; + + } + } +} 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 92da73da..7aea415b 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,31 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using FreeRedis; -using Mapster; -using Microsoft.Extensions.Options; +using Mapster; using Volo.Abp.Application.Services; -using Volo.Abp.Caching; -using Volo.Abp.DependencyInjection; -using Yi.Framework.ChatHub.Application.Contracts.Dtos; -using Yi.Framework.ChatHub.Domain.Shared.Caches; +using Yi.Framework.ChatHub.Domain.Managers; +using Yi.Framework.ChatHub.Domain.Shared.Model; namespace Yi.Framework.ChatHub.Application.Services { public class ChatUserService : ApplicationService { - /// - /// 使用懒加载防止报错 - /// - private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService(); - private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>().Value.KeyPrefix; - public async Task> GetListAsync() + private UserMessageManager _messageManager; + public ChatUserService(UserMessageManager messageManager) { _messageManager = messageManager; } + + public async Task> GetListAsync() { - var key = new ChatOnlineUserCacheKey(CacheKeyPrefix); - var cacheUsers = (await RedisClient.HGetAllAsync(key.GetKey())).Select(x => System.Text.Json.JsonSerializer.Deserialize < ChatOnlineUserCacheItem >( x.Value)).ToList(); - var output = cacheUsers.Adapt>(); + var userList = await _messageManager.GetAllUserAsync(); + var output = userList.Adapt>(); return output; } } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs index f059a53a..9fbcc413 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Consts/ChatConst.cs @@ -9,5 +9,8 @@ namespace Yi.Framework.ChatHub.Domain.Shared.Consts public class ChatConst { public const string AllGroupName = "all"; + + public const string ClientActionReceiveMsg = "receiveMsg"; + public const string ClientActionUserStatus = "userStatus"; } } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs similarity index 82% rename from Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs rename to Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs index 3980460f..698e2d44 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application.Contracts/Dtos/ChatUserGetListOutputDto.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/ChatUserModel.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Yi.Framework.ChatHub.Application.Contracts.Dtos +namespace Yi.Framework.ChatHub.Domain.Shared.Model { - public class ChatUserGetListOutputDto + public class ChatUserModel { /// /// 用户id @@ -22,5 +22,6 @@ namespace Yi.Framework.ChatHub.Application.Contracts.Dtos /// 用户头像 /// 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 new file mode 100644 index 00000000..6cc75c70 --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Yi.Framework.ChatHub.Domain.Shared.Model +{ + public class MessageContext + { + public static MessageContext CreatePersonal(string content, Guid userId,Guid sendUserId) + { + return new MessageContext() { MessageType = MessageType.Personal, Content = content, ReceiveId = userId ,SendUserId= sendUserId }; + } + + public static MessageContext CreateAll(string content, Guid sendUserId) + { + return new MessageContext() { MessageType = MessageType.All, Content = content, SendUserId = sendUserId }; + } + + + /// + /// 消息类型 + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public MessageType MessageType { get; set; } + /// + /// 接收者(用户id、群组id) + /// + public Guid? ReceiveId { get; set; } + + /// + /// 发送者的用户id + /// + public Guid SendUserId { get; set; } + /// + /// 消息内容 + /// + public string Content { get; set; } + + } + + public enum MessageType + { + + Personal, + Group, + All + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj index 95fbf7f0..f5a0fbe6 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Yi.Framework.ChatHub.Domain.Shared.csproj @@ -3,7 +3,6 @@ - diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs new file mode 100644 index 00000000..eba80b5e --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs @@ -0,0 +1,66 @@ +using FreeRedis; +using Mapster; +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Options; +using Volo.Abp.Caching; +using Volo.Abp.Domain.Services; +using Yi.Framework.ChatHub.Domain.Shared.Caches; +using Yi.Framework.ChatHub.Domain.Shared.Consts; +using Yi.Framework.ChatHub.Domain.Shared.Model; +using Yi.Framework.ChatHub.Domain.SignalRHubs; + +namespace Yi.Framework.ChatHub.Domain.Managers +{ + public class UserMessageManager : DomainService + { + private IHubContext _hubContext; + public UserMessageManager(IHubContext hubContext) + { + _hubContext = hubContext; + } + /// + /// 使用懒加载防止报错 + /// + private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService(); + private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>().Value.KeyPrefix; + + public async Task SendMessageAsync(MessageContext context) + { + switch (context.MessageType) + { + case MessageType.Personal: + var userModel =await GetUserAsync(context.ReceiveId.Value); + if (userModel is not null) + { + await _hubContext.Clients.Client(userModel.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context); + } + break; + case MessageType.Group: + throw new NotImplementedException(); + break; + case MessageType.All: + await _hubContext.Clients.All.SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context); + break; + default: + break; + } + + } + + public async Task> GetAllUserAsync() + { + var key = new ChatOnlineUserCacheKey(CacheKeyPrefix); + var cacheUsers = (await RedisClient.HGetAllAsync(key.GetKey())).Select(x => System.Text.Json.JsonSerializer.Deserialize(x.Value)).ToList(); + return cacheUsers; + } + + public async Task GetUserAsync(Guid userId) + { + var key = new ChatOnlineUserCacheKey(CacheKeyPrefix); + var cacheUser = System.Text.Json.JsonSerializer.Deserialize < ChatOnlineUserCacheItem >( await RedisClient.HGetAsync(key.GetKey(), key.GetField(userId))); + return cacheUser; + } + } + + +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/SignalRHubs/ChatCenterHub.cs similarity index 90% rename from Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs rename to Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/SignalRHubs/ChatCenterHub.cs index 4dc09c99..c216cad4 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/SignalRHubs/ChatHub.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/SignalRHubs/ChatCenterHub.cs @@ -5,16 +5,15 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.Caching; -using Volo.Abp.DependencyInjection; -using Yi.Framework.ChatHub.Application.Contracts.Dtos; using Yi.Framework.ChatHub.Domain.Shared.Caches; using Yi.Framework.ChatHub.Domain.Shared.Consts; +using Yi.Framework.ChatHub.Domain.Shared.Model; -namespace Yi.Framework.ChatHub.Application.SignalRHubs +namespace Yi.Framework.ChatHub.Domain.SignalRHubs { [HubRoute("/hub/chat")] [Authorize] - public class ChatHub : AbpHub + public class ChatCenterHub : AbpHub { /// /// 使用懒加载防止报错 @@ -24,7 +23,7 @@ namespace Yi.Framework.ChatHub.Application.SignalRHubs /// 缓存前缀 /// private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>().Value.KeyPrefix; - public ChatHub() + public ChatCenterHub() { } @@ -48,7 +47,7 @@ namespace Yi.Framework.ChatHub.Application.SignalRHubs //连接时,还需要去查询用户包含在的群组,将群主全部加入.Todo await Groups.AddToGroupAsync(Context.ConnectionId, ChatConst.AllGroupName); - await Clients.All.SendAsync("liveUser", item.Adapt()); + await Clients.All.SendAsync("liveUser", item.Adapt()); } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj index d478ffca..665f37cf 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj @@ -7,7 +7,6 @@ - @@ -19,7 +18,6 @@ - diff --git a/Yi.Bbs.Vue3/src/apis/chatMessageApi.js b/Yi.Bbs.Vue3/src/apis/chatMessageApi.js new file mode 100644 index 00000000..3d820226 --- /dev/null +++ b/Yi.Bbs.Vue3/src/apis/chatMessageApi.js @@ -0,0 +1,18 @@ +import request from "@/config/axios/service"; + +export function sendPersonalMessage(data) { + return request({ + url: "/chat-message/personal", + method: "post", + data + }); +} + +export function sendGroupMessage(data) { + return request({ + url: "/chat-message/group", + method: "post", + data + }); + } + \ No newline at end of file diff --git a/Yi.Bbs.Vue3/src/assets/chat_images/yilogo.png b/Yi.Bbs.Vue3/src/assets/chat_images/yilogo.png new file mode 100644 index 00000000..226b005a Binary files /dev/null and b/Yi.Bbs.Vue3/src/assets/chat_images/yilogo.png differ diff --git a/Yi.Bbs.Vue3/src/hubs/chatHub.js b/Yi.Bbs.Vue3/src/hubs/chatHub.js index 6f4d4302..e069b672 100644 --- a/Yi.Bbs.Vue3/src/hubs/chatHub.js +++ b/Yi.Bbs.Vue3/src/hubs/chatHub.js @@ -13,7 +13,7 @@ const receiveMsg = (connection) => { }); //接受其他用户消息 connection.on("receiveMsg", (type, content) => { - + chatStore.addMsg(content); }); //用户状态-正在输入中,无 connection.on("userStatus", (type) => { diff --git a/Yi.Bbs.Vue3/src/stores/chat.js b/Yi.Bbs.Vue3/src/stores/chat.js index 16d779f9..803a3dbf 100644 --- a/Yi.Bbs.Vue3/src/stores/chat.js +++ b/Yi.Bbs.Vue3/src/stores/chat.js @@ -1,25 +1,28 @@ import { defineStore } from "pinia"; - const chatStore = defineStore("chat", { state: () => ({ userList: [], + msgList: [] }), -// getters: { -// userListData: (state) => state.userList, -// }, - actions: { - // 设置在线总数 + getters: { + allMsgContext: (state) => state.msgList.filter(x=>x.messageType=="All"), + personalMsgContext: (state) => state.msgList.filter(x=>x.messageType=="Personal"), + }, + actions: + { + setMsgList(value) { + this.msgList = value; + }, + addMsg(msg) { + this.msgList.push(msg); + }, setUserList(value) { this.userList = value; }, - addUser(user) - { - + addUser(user) { this.userList.push(user); }, - delUser(userId) - { - + delUser(userId) { this.userList = this.userList.filter(obj => obj.userId != userId); } }, diff --git a/Yi.Bbs.Vue3/src/views/chathub/Index.vue b/Yi.Bbs.Vue3/src/views/chathub/Index.vue index 1afcf60c..6884650d 100644 --- a/Yi.Bbs.Vue3/src/views/chathub/Index.vue +++ b/Yi.Bbs.Vue3/src/views/chathub/Index.vue @@ -1,18 +1,162 @@ \ No newline at end of file