Ver código fonte

增加SignalR及优化其他

zuohuaijun 4 anos atrás
pai
commit
3f4badf2a8

+ 4 - 4
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -20,10 +20,10 @@
 
   <ItemGroup>
     <PackageReference Include="Caching.CSRedis" Version="3.8.2" />
-    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="3.5.3" />
-    <PackageReference Include="Furion.Extras.Logging.Serilog" Version="3.5.3" />
-    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="3.5.3" />
-    <PackageReference Include="Furion.Pure" Version="3.5.3" />
+    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="3.5.7" />
+    <PackageReference Include="Furion.Extras.Logging.Serilog" Version="3.5.7" />
+    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="3.5.7" />
+    <PackageReference Include="Furion.Pure" Version="3.5.7" />
     <PackageReference Include="Magicodes.IE.Excel" Version="2.6.4" />
     <PackageReference Include="MySql.Data" Version="8.0.29" />
     <PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.1.5" />

+ 153 - 0
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -2264,6 +2264,31 @@
             按钮
             </summary>
         </member>
+        <member name="T:Admin.NET.Core.MessageTypeEnum">
+            <summary>
+            消息类型枚举
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.MessageTypeEnum.Info">
+            <summary>
+            普通信息
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.MessageTypeEnum.Success">
+            <summary>
+            成功提示
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.MessageTypeEnum.Warning">
+            <summary>
+            警告提示
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.MessageTypeEnum.Error">
+            <summary>
+            错误提示
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.OrgTypeEnum">
             <summary>
             机构类型枚举
@@ -2785,6 +2810,95 @@
              <param name="next"></param>
              <returns></returns>
         </member>
+        <member name="T:Admin.NET.Core.ChatHub">
+            <summary>
+            聊天集线器
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.ChatHub.OnConnectedAsync">
+            <summary>
+            连接
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.ChatHub.OnDisconnectedAsync(System.Exception)">
+            <summary>
+            断开
+            </summary>
+            <param name="exception"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.ChatHub.ClientsSendMessage(Admin.NET.Core.MessageInput)">
+            <summary>
+            前端调用发送方法(发送信息给某个人)
+            </summary>
+            <param name="_message"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.ChatHub.ClientsSendMessagetoAll(Admin.NET.Core.MessageInput)">
+            <summary>
+            前端调用发送方法(发送信息给所有人)
+            </summary>
+            <param name="_message"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.ChatHub.ClientsSendMessagetoOther(Admin.NET.Core.MessageInput)">
+            <summary>
+            前端调用发送方法(发送消息给除了发送人的其他人)
+            </summary>
+            <param name="_message"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.ChatHub.ClientsSendMessagetoUsers(Admin.NET.Core.MessageInput)">
+            <summary>
+            前端调用发送方法(发送消息给某些人)
+            </summary>
+            <param name="_message"></param>
+            <returns></returns>
+        </member>
+        <member name="P:Admin.NET.Core.MessageInput.UserId">
+            <summary>
+            用户ID
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.MessageInput.UserIds">
+            <summary>
+            用户ID列表
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.MessageInput.Title">
+            <summary>
+            消息标题
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.MessageInput.Message">
+            <summary>
+            消息内容
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.MessageInput.MessageType">
+            <summary>
+            消息类型
+            </summary>
+        </member>
+        <member name="T:Admin.NET.Core.IChatClient">
+            <summary>
+            聊天客户端接口定义
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.IChatClient.ForceExist">
+            <summary>
+            强制下线
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.IChatClient.ReceiveMessage(System.Object)">
+            <summary>
+            发送信息
+            </summary>
+            <param name="context"></param>
+            <returns></returns>
+        </member>
         <member name="T:Admin.NET.Core.CacheOptions">
             <summary>
             缓存配置选项
@@ -4982,6 +5096,45 @@
             </summary>
             <returns></returns>
         </member>
+        <member name="M:Admin.NET.Core.Service.ISendMessageService.SendMessageToUser(System.String,System.String,Admin.NET.Core.MessageTypeEnum,System.Int64)">
+            <summary>
+            发送消息给某个人
+            </summary>
+            <param name="title">发送标题</param>
+            <param name="message">发送内容</param>
+            <param name="userId">接收人</param>
+            <param name="type">消息类型</param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ISendMessageService.SendMessageToUsers(System.String,System.String,Admin.NET.Core.MessageTypeEnum,System.Collections.Generic.List{System.Int64})">
+            <summary>
+            发送消息给某些人
+            </summary>
+            <param name="title">发送标题</param>
+            <param name="message">发送内容</param>
+            <param name="userId">接收人列表</param>
+            <param name="type">消息类型</param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ISendMessageService.SendMessageToAllUser(System.String,System.String,Admin.NET.Core.MessageTypeEnum)">
+            <summary>
+            发送消息给所有人
+            </summary>
+            <param name="title">发送标题</param>
+            <param name="message">发送内容</param>
+            <param name="type">消息类型</param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ISendMessageService.SendMessageToOtherUser(System.String,System.String,Admin.NET.Core.MessageTypeEnum,System.Int64)">
+            <summary>
+            发送消息给除了发送人的其他人
+            </summary>
+            <param name="title">发送标题</param>
+            <param name="message">发送内容</param>
+            <param name="userId">发送人</param>
+            <param name="type">消息类型</param>
+            <returns></returns>
+        </member>
         <member name="P:Admin.NET.Core.Service.OrgInput.Pid">
             <summary>
             父Id

+ 31 - 0
Admin.NET/Admin.NET.Core/Enum/MessageTypeEnum.cs

@@ -0,0 +1,31 @@
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 消息类型枚举
+/// </summary>
+public enum MessageTypeEnum
+{
+    /// <summary>
+    /// 普通信息
+    /// </summary>
+    [Description("消息")]
+    Info = 0,
+
+    /// <summary>
+    /// 成功提示
+    /// </summary>
+    [Description("成功")]
+    Success = 1,
+
+    /// <summary>
+    /// 警告提示
+    /// </summary>
+    [Description("警告")]
+    Warning = 2,
+
+    /// <summary>
+    /// 错误提示
+    /// </summary>
+    [Description("错误")]
+    Error = 3
+}

+ 110 - 0
Admin.NET/Admin.NET.Core/Hub/ChatHub.cs

@@ -0,0 +1,110 @@
+using Microsoft.AspNetCore.SignalR;
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 聊天集线器
+/// </summary>
+public class ChatHub : Hub<IChatClient>
+{
+    private readonly ISysCacheService _cache;
+    private readonly ISendMessageService _sendMessageService;
+
+    public ChatHub(ISysCacheService cache, 
+        ISendMessageService sendMessageService)
+    {
+        _cache = cache;
+        _sendMessageService = sendMessageService;
+    }
+
+    /// <summary>
+    /// 连接
+    /// </summary>
+    /// <returns></returns>
+    public override async Task OnConnectedAsync()
+    {
+        //var token = Context.GetHttpContext().Request.Query["access_token"];
+        //var claims = JWTEncryption.ReadJwtToken(token)?.Claims;
+
+        //var client = Parser.GetDefault().Parse(Context.GetHttpContext().Request.Headers["User-Agent"]);
+        //var loginBrowser = client.UA.Family + client.UA.Major;
+        //var loginOs = client.OS.Family + client.OS.Major;
+
+        //var userId = claims.FirstOrDefault(e => e.Type == ClaimConst.CLAINM_USERID)?.Value;
+        //var account = claims.FirstOrDefault(e => e.Type == ClaimConst.CLAINM_ACCOUNT)?.Value;
+        //var name = claims.FirstOrDefault(e => e.Type == ClaimConst.CLAINM_NAME)?.Value;
+        //var tenantId = claims.FirstOrDefault(e => e.Type == ClaimConst.TENANT_ID)?.Value;
+        //var onlineUsers = await _cache.GetAsync<List<OnlineUser>>(CommonConst.CACHE_KEY_ONLINE_USER) ?? new List<OnlineUser>();
+        //onlineUsers.Add(new OnlineUser
+        //{
+        //    ConnectionId = Context.ConnectionId,
+        //    UserId = long.Parse(userId),
+        //    LastTime = DateTime.Now,
+        //    LastLoginIp = App.HttpContext.GetRequestIPv4(),
+        //    LastLoginBrowser = loginBrowser,
+        //    LastLoginOs = loginOs,
+        //    Account = account,
+        //    Name = name,
+        //    TenantId = Convert.ToInt64(tenantId),
+        //});
+        //await _cache.SetAsync(CommonConst.CACHE_KEY_ONLINE_USER, onlineUsers);
+    }
+
+    /// <summary>
+    /// 断开
+    /// </summary>
+    /// <param name="exception"></param>
+    /// <returns></returns>
+    public override async Task OnDisconnectedAsync(Exception exception)
+    {
+        //if (!string.IsNullOrEmpty(Context.ConnectionId))
+        //{
+        //    var onlineUsers = await _cache.GetAsync<List<OnlineUser>>(CommonConst.CACHE_KEY_ONLINE_USER);
+        //    if (onlineUsers == null) return;
+
+        //    onlineUsers.RemoveAll(u => u.ConnectionId == Context.ConnectionId);
+        //    await _cache.SetAsync(CommonConst.CACHE_KEY_ONLINE_USER, onlineUsers);
+        //}
+    }
+
+    /// <summary>
+    /// 前端调用发送方法(发送信息给某个人)
+    /// </summary>
+    /// <param name="_message"></param>
+    /// <returns></returns>
+    public async Task ClientsSendMessage(MessageInput _message)
+    {
+        await _sendMessageService.SendMessageToUser(_message.Title, _message.Message, _message.MessageType, _message.UserId);
+    }
+
+    /// <summary>
+    /// 前端调用发送方法(发送信息给所有人)
+    /// </summary>
+    /// <param name="_message"></param>
+    /// <returns></returns>
+    public async Task ClientsSendMessagetoAll(MessageInput _message)
+    {
+        await _sendMessageService.SendMessageToAllUser(_message.Title, _message.Message, _message.MessageType);
+    }
+
+    /// <summary>
+    /// 前端调用发送方法(发送消息给除了发送人的其他人)
+    /// </summary>
+    /// <param name="_message"></param>
+    /// <returns></returns>
+    public async Task ClientsSendMessagetoOther(MessageInput _message)
+    {
+        // _message.userId为发送人ID
+        await _sendMessageService.SendMessageToOtherUser(_message.Title, _message.Message, _message.MessageType, _message.UserId);
+    }
+
+    /// <summary>
+    /// 前端调用发送方法(发送消息给某些人)
+    /// </summary>
+    /// <param name="_message"></param>
+    /// <returns></returns>
+    public async Task ClientsSendMessagetoUsers(MessageInput _message)
+    {
+        await _sendMessageService.SendMessageToUsers(_message.Title, _message.Message, _message.MessageType, _message.UserIds);
+    }
+}

+ 29 - 0
Admin.NET/Admin.NET.Core/Hub/Dto/MessageInput.cs

@@ -0,0 +1,29 @@
+namespace Admin.NET.Core;
+
+public class MessageInput
+{
+    /// <summary>
+    /// 用户ID
+    /// </summary>
+    public long UserId { get; set; }
+
+    /// <summary>
+    /// 用户ID列表
+    /// </summary>
+    public List<long> UserIds { get; set; }
+
+    /// <summary>
+    /// 消息标题
+    /// </summary>
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    public string Message { get; set; }
+
+    /// <summary>
+    /// 消息类型
+    /// </summary>
+    public MessageTypeEnum MessageType { get; set; }
+}

+ 20 - 0
Admin.NET/Admin.NET.Core/Hub/IChatClient.cs

@@ -0,0 +1,20 @@
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 聊天客户端接口定义
+/// </summary>
+public interface IChatClient
+{
+    /// <summary>
+    /// 强制下线
+    /// </summary>
+    /// <returns></returns>
+    Task ForceExist();
+
+    /// <summary>
+    /// 发送信息
+    /// </summary>
+    /// <param name="context"></param>
+    /// <returns></returns>
+    Task ReceiveMessage(object context);
+}

+ 43 - 0
Admin.NET/Admin.NET.Core/Service/Message/ISendMessageService.cs

@@ -0,0 +1,43 @@
+namespace Admin.NET.Core.Service;
+
+public interface ISendMessageService
+{
+    /// <summary>
+    /// 发送消息给某个人
+    /// </summary>
+    /// <param name="title">发送标题</param>
+    /// <param name="message">发送内容</param>
+    /// <param name="userId">接收人</param>
+    /// <param name="type">消息类型</param>
+    /// <returns></returns>
+    Task SendMessageToUser(string title, string message, MessageTypeEnum type, long userId);
+
+    /// <summary>
+    /// 发送消息给某些人
+    /// </summary>
+    /// <param name="title">发送标题</param>
+    /// <param name="message">发送内容</param>
+    /// <param name="userId">接收人列表</param>
+    /// <param name="type">消息类型</param>
+    /// <returns></returns>
+    Task SendMessageToUsers(string title, string message, MessageTypeEnum type, List<long> userId);
+
+    /// <summary>
+    /// 发送消息给所有人
+    /// </summary>
+    /// <param name="title">发送标题</param>
+    /// <param name="message">发送内容</param>
+    /// <param name="type">消息类型</param>
+    /// <returns></returns>
+    Task SendMessageToAllUser(string title, string message, MessageTypeEnum type);
+
+    /// <summary>
+    /// 发送消息给除了发送人的其他人
+    /// </summary>
+    /// <param name="title">发送标题</param>
+    /// <param name="message">发送内容</param>
+    /// <param name="userId">发送人</param>
+    /// <param name="type">消息类型</param>
+    /// <returns></returns>
+    Task SendMessageToOtherUser(string title, string message, MessageTypeEnum type, long userId);
+}

+ 99 - 0
Admin.NET/Admin.NET.Core/Service/Message/SendMessageService.cs

@@ -0,0 +1,99 @@
+//using Microsoft.AspNetCore.SignalR;
+
+//namespace Admin.NET.Core.Service;
+
+///// <summary>
+///// 消息发送服务
+///// </summary>
+//[ApiDescriptionSettings(Name = "Message", Order = 100)]
+//[Route("api")]
+//public class SendMessageService : ISendMessageService, IDynamicApiController, ITransient
+//{
+//    private readonly ISysCacheService _sysCacheService;
+//    private readonly IHubContext<ChatHub, IChatClient> _chatHubContext;
+
+//    public SendMessageService(ISysCacheService sysCacheService,
+//        IHubContext<ChatHub, IChatClient> chatHubContext)
+//    {
+//        _sysCacheService = sysCacheService;
+//        _chatHubContext = chatHubContext;
+//    }
+
+//    /// <summary>
+//    /// 发送消息给所有人
+//    /// </summary>
+//    /// <param name="title">发送标题</param>
+//    /// <param name="message">发送内容</param>
+//    /// <param name="type">消息类型</param>
+//    /// <returns></returns>
+//    [HttpGet("sysMessage/allUser")]
+//    public async Task SendMessageToAllUser(string title, string message, MessageTypeEnum type)
+//    {
+//        await _chatHubContext.Clients.All.ReceiveMessage(new { Title = title, Message = message, Messagetype = type });
+//    }
+
+//    /// <summary>
+//    /// 发送消息给除了发送人的其他人
+//    /// </summary>
+//    /// <param name="title">发送标题</param>
+//    /// <param name="message">发送内容</param>
+//    /// <param name="userId">发送人</param>
+//    /// <param name="type">消息类型</param>
+//    /// <returns></returns>
+//    [HttpGet("sysMessage/otherUser")]
+//    public async Task SendMessageToOtherUser(string title, string message, MessageTypeEnum type, long userId)
+//    {
+//        var onlineuserlist = await _sysCacheService.GetAsync<List<OnlineUser>>(CommonConst.CACHE_KEY_ONLINE_USER);
+
+//        var user = onlineuserlist.Where(x => x.UserId == userId).ToList();
+//        if (user != null)
+//        {
+//            await _chatHubContext.Clients.AllExcept(user[0].ConnectionId).ReceiveMessage(new { title = title, message = message, messagetype = type });
+//        }
+//    }
+
+//    /// <summary>
+//    /// 发送消息给某个人
+//    /// </summary>
+//    /// <param name="title">发送标题</param>
+//    /// <param name="message">发送内容</param>
+//    /// <param name="userId">接收人</param>
+//    /// <param name="type">消息类型</param>
+//    /// <returns></returns>
+//    [HttpGet("sysMessage/user")]
+//    public async Task SendMessageToUser(string title, string message, MessageTypeEnum type, long userId)
+//    {
+//        var onlineuserlist = await _sysCacheService.GetAsync<List<OnlineUser>>(CommonConst.CACHE_KEY_ONLINE_USER);
+
+//        var user = onlineuserlist.Where(x => x.UserId == userId).ToList();
+//        if (user != null)
+//        {
+//            foreach (var item in user)
+//            {
+//                await _chatHubContext.Clients.Client(item.ConnectionId).ReceiveMessage(new { title = title, message = message, messagetype = type });
+//            }
+//        }
+//    }
+
+//    /// <summary>
+//    /// 发送消息给某些人
+//    /// </summary>
+//    /// <param name="title">发送标题</param>
+//    /// <param name="message">发送内容</param>
+//    /// <param name="userId">接收人列表</param>
+//    /// <param name="type">消息类型</param>
+//    /// <returns></returns>
+//    [HttpGet("sysMessage/users")]
+//    public async Task SendMessageToUsers(string title, string message, MessageTypeEnum type, List<long> userId)
+//    {
+//        var onlineuserlist = await _sysCacheService.GetAsync<List<OnlineUser>>(CommonConst.CACHE_KEY_ONLINE_USER);
+
+//        var userlist = new List<string>();
+//        foreach (var item in onlineuserlist)
+//        {
+//            if (userId.Contains(item.UserId))
+//                userlist.Add(item.ConnectionId);
+//        }
+//        await _chatHubContext.Clients.Clients(userlist).ReceiveMessage(new { Title = title, Message = message, Messagetype = type });
+//    }
+//}

+ 3 - 8
Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs

@@ -179,15 +179,10 @@ public static class SqlSugarSetup
             if (seedDataTable.Columns.Contains(SqlSugarConst.PrimaryKey))
             {
                 var storage = provider.Storageable(seedDataTable).WhereColumns(SqlSugarConst.PrimaryKey).ToStorage();
-                //如果添加一条种子数,sqlsugar默认会通过@param的方式赋值,如果PropertyType为空,则默认数据类型为字符串。插入pgsql时候会报错, 所以要忽略为空的值添加
-                if (((InsertableProvider<System.Collections.Generic.Dictionary<string, object>>)storage.AsInsertable).IsSingle)
-                {
-                    storage.AsInsertable.IgnoreColumns("UpdateTime", "UpdateUserId", "CreateUserId").ExecuteCommand();
-                }
-                else
-                {
+                // 如果添加一条种子数,sqlsugar默认会通过@param的方式赋值,如果PropertyType为空,则默认数据类型为字符串。插入pgsql时候会报错,所以要忽略为空的值添加
+                _ = ((InsertableProvider<Dictionary<string, object>>)storage.AsInsertable).IsSingle ?
+                    storage.AsInsertable.IgnoreColumns("UpdateTime", "UpdateUserId", "CreateUserId").ExecuteCommand() :
                     storage.AsInsertable.ExecuteCommand();
-                }
                 storage.AsUpdateable.ExecuteCommand();
             }
             else //没有主键或者不是预定义的主键(没主键有重复的可能)

+ 6 - 0
Admin.NET/Admin.NET.Web.Core/Startup.cs

@@ -75,6 +75,9 @@ namespace Admin.NET.Web.Core
             // 注册模板引擎
             services.AddViewEngine();
 
+            // 注册即时通讯
+            services.AddSignalR();
+
             // 增加Logo输出显示
             services.AddLogoDisplay();
         }
@@ -111,6 +114,9 @@ namespace Admin.NET.Web.Core
 
             app.UseEndpoints(endpoints =>
             {
+                // 注册集线器
+                endpoints.MapHubs();
+
                 endpoints.MapControllerRoute(
                     name: "default",
                     pattern: "{controller=Home}/{action=Index}/{id?}");