Browse Source

Merge branch 'develop' of http://132.232.92.186:3000/XinXiBu/OA2023 into develop

yuanrf 1 year ago
parent
commit
5f2dfa9515

+ 7 - 2
OASystem/OASystem.Api/Controllers/AuthController.cs

@@ -18,6 +18,7 @@ using Microsoft.AspNetCore.SignalR;
 using OASystem.API.OAMethodLib.Hub.Hubs;
 using OASystem.API.OAMethodLib.Hub.Hubs;
 using OASystem.API.OAMethodLib.Hub.HubClients;
 using OASystem.API.OAMethodLib.Hub.HubClients;
 using static OASystem.API.OAMethodLib.Hub.Hubs.ChatHub;
 using static OASystem.API.OAMethodLib.Hub.Hubs.ChatHub;
+using static OASystem.API.OAMethodLib.JWTHelper;
 
 
 namespace OASystem.API.Controllers
 namespace OASystem.API.Controllers
 {
 {
@@ -72,12 +73,14 @@ namespace OASystem.API.Controllers
             #endregion
             #endregion
             Result authData = null;
             Result authData = null;
             string uName = string.Empty;
             string uName = string.Empty;
+            string role = string.Empty;
             int uId = 0;
             int uId = 0;
             int unReadCount = 0;
             int unReadCount = 0;
             if (userData.Data != null)
             if (userData.Data != null)
             {
             {
                 uId = (userData.Data as UserLoginInfoView).UserId;
                 uId = (userData.Data as UserLoginInfoView).UserId;
                 uName = (userData.Data as UserLoginInfoView).CnName;
                 uName = (userData.Data as UserLoginInfoView).CnName;
+                role = (userData.Data as UserLoginInfoView).JobName;
                 authData = _SystemMenuPermissionRepository.QueryMenuLoad(uId, dto.PortType);
                 authData = _SystemMenuPermissionRepository.QueryMenuLoad(uId, dto.PortType);
                 unReadCount = await _messageRep.GetUnReadCount(uId);
                 unReadCount = await _messageRep.GetUnReadCount(uId);
             }
             }
@@ -103,7 +106,8 @@ namespace OASystem.API.Controllers
 
 
                 if (expDt >= createZebraTime)  //超时重新获取token
                 if (expDt >= createZebraTime)  //超时重新获取token
                 {
                 {
-                    authorToken = await GeneralMethod.GetToken(_config, dto.Number, uId,uName, createZebraTime);
+                    //authorToken = await GeneralMethod.GetToken(_config, dto.Number, uId,uName, createZebraTime);
+                    authorToken = await JwtHelper.IssueJwtAsync(new TokenModelJwt() { UserId = uId, UserName = uName,Role = role }); //
                 }
                 }
 
 
                 view.Expires = expDt;
                 view.Expires = expDt;
@@ -112,7 +116,8 @@ namespace OASystem.API.Controllers
             else
             else
             {
             {
                 view.Expires = createZebraTime.AddMinutes(30);
                 view.Expires = createZebraTime.AddMinutes(30);
-                view.Token = await GeneralMethod.GetToken(_config, dto.Number, uId, uName, createZebraTime);
+                //view.Token = await GeneralMethod.GetToken(_config, dto.Number, uId, uName, createZebraTime); //JwtHelper
+                view.Token = await JwtHelper.IssueJwtAsync(new TokenModelJwt (){ UserId = uId,UserName = uName,Role = role }); //
                 TimeSpan ts = view.Expires.AddMinutes(-1) - createZebraTime; //设置redis 过期时间 比 jwt 时间 快一分钟
                 TimeSpan ts = view.Expires.AddMinutes(-1) - createZebraTime; //设置redis 过期时间 比 jwt 时间 快一分钟
                 await RedisRepository.RedisFactory.CreateRedisRepository().StringSetAsync<string>(authorId, view.Token, ts);//string 存
                 await RedisRepository.RedisFactory.CreateRedisRepository().StringSetAsync<string>(authorId, view.Token, ts);//string 存
 
 

+ 11 - 7
OASystem/OASystem.Api/Controllers/ClientHubController.cs

@@ -23,11 +23,11 @@ namespace OASystem.API.Controllers
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// 获取所有的用户
+        /// 获取在线用户
         /// </summary>
         /// </summary>
         /// <returns></returns>
         /// <returns></returns>
-        [HttpGet("GetAllUserIds", Name = "GetAllUserIds")]
-        public List<UserModel> GetAllUserIds()
+        [HttpGet("GetOnlineUsers", Name = "GetOnlineUsers")]
+        public List<UserModel> GetOnlineUsers()
         {
         {
             return UserStore.OnlineUser;
             return UserStore.OnlineUser;
         }
         }
@@ -43,7 +43,7 @@ namespace OASystem.API.Controllers
         [HttpPost("SendAllUserMessage", Name = "SendAllUserMessage")]
         [HttpPost("SendAllUserMessage", Name = "SendAllUserMessage")]
         public async Task<IActionResult> SendAllUserMessage( string msg)
         public async Task<IActionResult> SendAllUserMessage( string msg)
         {
         {
-            await _hubContext.Clients.All.SendAll(msg);
+            await _hubContext.Clients.All.ReceiveMessage(msg);
             return Ok("Send Successful!");
             return Ok("Send Successful!");
         }
         }
 
 
@@ -55,17 +55,21 @@ namespace OASystem.API.Controllers
         /// <param name="hubContext"></param>
         /// <param name="hubContext"></param>
         /// <returns></returns>
         /// <returns></returns>
         [HttpPost("SendCustomUserMessage", Name = "SendCustomUserMessage")]
         [HttpPost("SendCustomUserMessage", Name = "SendCustomUserMessage")]
-        public async Task<IActionResult> SendCustomUserMessage(int userid,string date )
+        public async Task<IActionResult> SendCustomUserMessage(int userId,string date )
         {
         {
             string connId = string.Empty;
             string connId = string.Empty;
 
 
-            UserModel user = UserStore.OnlineUser.Where(it => it.UserId == userid).FirstOrDefault();
+            UserModel user = UserStore.OnlineUser.Where(it => it.UserId == userId).FirstOrDefault();
             if (user != null)
             if (user != null)
             {
             {
                 connId = user.ConnectionId;
                 connId = user.ConnectionId;
             }
             }
+            else
+            {
+                return Ok("Send Failed! User Not Online!");
+            }
 
 
-            await _hubContext.Clients.Client(connId).SendCustomUserMessage(date);
+            await _hubContext.Clients.Client(connId).ReceiveMessage(date);
             return Ok("Send Successful!");
             return Ok("Send Successful!");
         }
         }
     }
     }

+ 4 - 0
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -509,6 +509,10 @@ namespace OASystem.API.Controllers
                     diId = groupData.Data;
                     diId = groupData.Data;
                     GeneralMethod.PostGroupRateAddInit(dto.UserId, diId);
                     GeneralMethod.PostGroupRateAddInit(dto.UserId, diId);
                 }
                 }
+                else if(dto.Status == 2)
+                {
+                    diId = dto.Id;
+                }
 
 
                 return Ok(JsonView(true,"操作成功!", diId));
                 return Ok(JsonView(true,"操作成功!", diId));
             }
             }

+ 124 - 1
OASystem/OASystem.Api/Controllers/SystemController.cs

@@ -35,6 +35,10 @@ namespace OASystem.API.Controllers
         private readonly SetDataTypeRepository _setDataTypeRep;
         private readonly SetDataTypeRepository _setDataTypeRep;
         private readonly UserAuthorityRepository _UserAuthorityRepository;
         private readonly UserAuthorityRepository _UserAuthorityRepository;
 
 
+
+        private readonly List<int> _operationTypeList = new List<int>() { 1, 2, 3, 4, 5 }; //操作通知所属类型
+        private readonly List<int> _taskTypeList = new List<int>() { 6 };//任务通知 TaskNotification
+
         public SystemController( CompanyRepository syscom, DepartmentRepository sysDepRep, UsersRepository userRep,
         public SystemController( CompanyRepository syscom, DepartmentRepository sysDepRep, UsersRepository userRep,
             IMapper mapper,SqlSugarClient sqlSugar, SetDataRepository setDataRepository, CompanyRepository companyRepository,
             IMapper mapper,SqlSugarClient sqlSugar, SetDataRepository setDataRepository, CompanyRepository companyRepository,
             SystemMenuPermissionRepository systemMenuPermissionRepository, PageFunctionPermissionRepository pageFunctionPermissionRepository,
             SystemMenuPermissionRepository systemMenuPermissionRepository, PageFunctionPermissionRepository pageFunctionPermissionRepository,
@@ -61,7 +65,7 @@ namespace OASystem.API.Controllers
         #region 消息
         #region 消息
 
 
         /// <summary>
         /// <summary>
-        /// 获取消息列表
+        /// 获取消息列表-整合版
         /// </summary>
         /// </summary>
         /// <param name="dto"></param>
         /// <param name="dto"></param>
         /// <returns></returns>
         /// <returns></returns>
@@ -79,6 +83,125 @@ namespace OASystem.API.Controllers
             return Ok(JsonView(true,"成功", msgData.Data));
             return Ok(JsonView(true,"成功", msgData.Data));
         }
         }
 
 
+        #region 消息列表 - 分开
+
+        /// <summary>
+        /// 系统消息
+        /// 消息类型  2024-03-06 14:37
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> PotsMsgTypeData(MsgTypeDto dto)
+        {
+            if (dto.PortType < 1 || dto.PortType > 3)
+            {
+                return Ok(JsonView(false, "请输入有效的PortType参数。1 Web 2 Android 3 IOS"));
+            }
+
+            if (dto.UserId < 1)
+            {
+                return Ok(JsonView(false, "请输入有效的UserId参数。"));
+            }
+
+            var msgData = await _messageRep.PotsMsgTypeData(dto);
+
+            if (msgData.Code != 0)
+            {
+                return Ok(JsonView(false, msgData.Msg));
+            }
+
+            return Ok(JsonView(true, "成功", msgData.Data));
+        }
+
+        /// <summary>
+        /// 系统消息
+        /// 消息List  2024-03-06 14:54
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> PotsMessagePageList(PotsMessagePageListDto dto)
+        {
+            #region 参数验证
+
+            if (dto.PortType < 1 || dto.PortType > 3)
+            {
+                return Ok(JsonView(false, "请输入有效的PortType参数。1 Web 2 Android 3 IOS"));
+            }
+
+            if (dto.Type < 1 || dto.Type > 2)
+            {
+                return Ok(JsonView(false, "请输入有效的Type参数。1 团组操作通知 2 任务操作通知"));
+            }
+            if (dto.UserId < 1)
+            {
+                return Ok(JsonView(false, "请输入有效的UserId参数。"));
+            }
+
+            #endregion
+
+
+            string msgSqlWhere = string.Format(@"Select sm.Id,sm.Type,sm.Title,sm.Content,sd.DepName issuerDep,su.CnName issuerUser, 
+                                                            sm.ReleaseTime,smra.Id AuthId,smra.ReadableUId,smra.IsRead,smra.ReadTime 
+                                                     From Sys_Message sm 
+                                                     Inner Join Sys_MessageReadAuth smra On sm.Id = smra.MsgId
+                                                     Inner Join Sys_Users su On sm.IssuerId = su.Id
+                                                     Inner Join Sys_Department sd On su.DepId = sd.Id
+                                                     Inner Join Sys_Users suAuth On smra.ReadableUId = suAuth.Id
+                                                     Where sm.IsDel = 0
+                                                     And smra.IsDel = 0 
+                                                     And smra.ReadableUId = {0}
+                                                     Order By ReleaseTime Desc ", dto.UserId);
+            var _readableMsgList = await _sqlSugar.SqlQueryable<ReadbleMessageView>(msgSqlWhere).ToListAsync();
+            if (_readableMsgList.Count > 0)
+            {
+
+                if (dto.PortType == 1 || dto.PortType == 2 || dto.PortType == 3)
+                {
+                    int pageSize = dto.PageSize; // 每页显示的记录数量
+                    int currentPage = dto.PageIndex; // 当前页码(从1开始)
+
+                    if (dto.Type == 1) //团组操作通知
+                    {
+                        //操作通知 OperationNotification
+                        var operationNotificationData = _readableMsgList.Where(it => _operationTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
+                        int operationNotificationDataCount = operationNotificationData.Count;
+                        // 计算起始索引和结束索引
+                        int operationStartIndex = (currentPage - 1) * pageSize;
+                        int operationEndIndex = Math.Min(operationStartIndex + pageSize, operationNotificationDataCount);
+
+                        var operationNotificationDataView = operationNotificationData.Skip(operationStartIndex).Take(pageSize).ToList();
+
+                        return Ok(JsonView(true, "成功", operationNotificationDataView, operationNotificationDataCount));
+                    }
+                    else if (dto.Type == 2) //2 任务操作通知
+                    {
+
+                        //任务通知 TaskNotification
+                        List<int> taskTypeList = new List<int>() { 6 };
+                        var taskNotificationData = _readableMsgList.Where(it => taskTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
+                        int taskNotificationDataCount = taskNotificationData.Count;
+                        // 计算起始索引和结束索引
+                        int taskStartIndex = (currentPage - 1) * pageSize;
+                        int taskEndIndex = Math.Min(taskStartIndex + pageSize, taskNotificationDataCount);
+
+                        var taskNotificationDataView = taskNotificationData.Skip(taskStartIndex).Take(pageSize).ToList();
+
+                        return Ok(JsonView(true, "成功", taskNotificationDataView, taskNotificationDataCount));
+                    }
+
+                }
+            }
+
+            return Ok(JsonView(true,"操作成功!" ,new List<int>() { }, 0));
+        }
+
+
+        #endregion
+
         /// <summary>
         /// <summary>
         /// 获取消息详细信息
         /// 获取消息详细信息
         /// </summary>
         /// </summary>

+ 3 - 3
OASystem/OASystem.Api/OAMethodLib/GeneralMethod.cs

@@ -111,10 +111,10 @@ namespace OASystem.API.OAMethodLib
                 expires: exp,
                 expires: exp,
                 signingCredentials: creds);
                 signingCredentials: creds);
 
 
-            //var indentity = new ClaimsIdentity(claims, "formlogin");
-            //var principal = new ClaimsPrincipal(indentity);
+            var indentity = new ClaimsIdentity(claims, "formlogin");
+            var principal = new ClaimsPrincipal(indentity);
 
 
-            // await _httpContext.SignInAsync (CookieAuthenticationDefaults.AuthenticationScheme, principal);
+             await _httpContext.SignInAsync (CookieAuthenticationDefaults.AuthenticationScheme, principal);
 
 
 
 
 
 

+ 36 - 18
OASystem/OASystem.Api/OAMethodLib/JwtHelper.cs

@@ -1,6 +1,13 @@
-using SqlSugar.Extensions;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Http;
+using NetTaste;
+using OASystem.API.OAMethodLib.JuHeAPI;
+using OASystem.Domain.Dtos.Business;
+using SqlSugar.Extensions;
 using System.IdentityModel.Tokens.Jwt;
 using System.IdentityModel.Tokens.Jwt;
 using System.Security.Claims;
 using System.Security.Claims;
+using static NPOI.HSSF.Util.HSSFColor;
 
 
 namespace OASystem.API.OAMethodLib
 namespace OASystem.API.OAMethodLib
 {
 {
@@ -9,17 +16,19 @@ namespace OASystem.API.OAMethodLib
         public class JwtHelper
         public class JwtHelper
         {
         {
 
 
+
+            private readonly static IHttpContextAccessor _httpContextAccessor = AutofacIocManager.Instance.GetService<IHttpContextAccessor>();
             /// <summary>
             /// <summary>
             /// 颁发JWT字符串
             /// 颁发JWT字符串
             /// </summary>
             /// </summary>
             /// <param name="tokenModel"></param>
             /// <param name="tokenModel"></param>
             /// <returns></returns>
             /// <returns></returns>
-            public static string IssueJwt(TokenModelJwt tokenModel)
+            public static async Task<string> IssueJwtAsync(TokenModelJwt tokenModel)
             {
             {
                 //  appsettign.json 操作类
                 //  appsettign.json 操作类
-                string iss = "Issuer";
-                string aud = "Audience";
-                string secret = "Audience";
+                string iss = "OASystem.com";
+                string aud = "OASystem.com";
+                string secret = AppSettingsHelper.Get("JwtSecurityKey");
 
 
                 var claims = new List<Claim>
                 var claims = new List<Claim>
               {
               {
@@ -29,11 +38,14 @@ namespace OASystem.API.OAMethodLib
                    2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。
                    2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。
                  */                
                  */                
 
 
-                new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
+                new Claim(JwtRegisteredClaimNames.Jti, tokenModel.UserId.ToString()),
+                //new Claim(JwtRegisteredClaimNames.GivenName, tokenModel.UserName),
+                new Claim("UserName", tokenModel.UserName),
+                //new Claim("UserId", tokenModel.UserId.ToString()),
                 new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                 new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                 new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                 new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                 //这个就是过期时间,目前是过期7200秒,可自定义,注意JWT有自己的缓冲过期时间
                 //这个就是过期时间,目前是过期7200秒,可自定义,注意JWT有自己的缓冲过期时间
-                new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(7200)).ToUnixTimeSeconds()}"),
+                new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(7200)).ToUnixTimeSeconds()}"),
                 new Claim(JwtRegisteredClaimNames.Iss,iss),
                 new Claim(JwtRegisteredClaimNames.Iss,iss),
                 new Claim(JwtRegisteredClaimNames.Aud,aud),
                 new Claim(JwtRegisteredClaimNames.Aud,aud),
                 
                 
@@ -55,6 +67,12 @@ namespace OASystem.API.OAMethodLib
                     //,expires:DateTime.Now.AddMinutes(1)
                     //,expires:DateTime.Now.AddMinutes(1)
                     );
                     );
 
 
+               // var indentity = new ClaimsIdentity(claims, "FMGJ-OASystem");
+               // var principal = new ClaimsPrincipal(indentity);
+
+               //await _httpContextAccessor.HttpContext?.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
+                
+
                 var jwtHandler = new JwtSecurityTokenHandler();
                 var jwtHandler = new JwtSecurityTokenHandler();
                 var encodedJwt = jwtHandler.WriteToken(jwt);
                 var encodedJwt = jwtHandler.WriteToken(jwt);
 
 
@@ -70,19 +88,22 @@ namespace OASystem.API.OAMethodLib
             {
             {
                 var jwtHandler = new JwtSecurityTokenHandler();
                 var jwtHandler = new JwtSecurityTokenHandler();
                 JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
                 JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
-                object role;
+                object role,userName;
                 try
                 try
                 {
                 {
                     jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
                     jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
+                    jwtToken.Payload.TryGetValue("UserName", out userName);
                 }
                 }
                 catch (Exception e)
                 catch (Exception e)
                 {
                 {
                     Console.WriteLine(e);
                     Console.WriteLine(e);
                     throw;
                     throw;
                 }
                 }
+
                 var tm = new TokenModelJwt
                 var tm = new TokenModelJwt
                 {
                 {
-                    Uid = (jwtToken.Id).ObjToInt(),
+                    UserId = (jwtToken.Id).ObjToInt(),
+                    UserName = userName != null ? userName.ObjToString() : "",
                     Role = role != null ? role.ObjToString() : "",
                     Role = role != null ? role.ObjToString() : "",
                 };
                 };
                 return tm;
                 return tm;
@@ -97,20 +118,17 @@ namespace OASystem.API.OAMethodLib
             /// <summary>
             /// <summary>
             /// Id
             /// Id
             /// </summary>
             /// </summary>
-            public long Uid { get; set; }
+            public int UserId { get; set; }
 
 
             public string UserName { get; set; }
             public string UserName { get; set; }
 
 
+            public string Role { get; set; } = "Admin";
+
             /// <summary>
             /// <summary>
-            /// 角色
-            /// </summary>
-            public string Role { get; set; }
-            /// <summary>
-            /// 职能
+            /// 过期时间,默认过期7200秒
+            /// 注意JWT有自己的缓冲过期时间
             /// </summary>
             /// </summary>
-            public string Work { get; set; }
-
-
+            public int ExpirationTime { get; set; } = 7200;
 
 
         }
         }
     }
     }

+ 18 - 0
OASystem/OASystem.Api/OAMethodLib/SignalR/HubClients/IChatClient.cs

@@ -11,5 +11,23 @@
         Task SendMessageByUser(object message);
         Task SendMessageByUser(object message);
 
 
         Task SendCustomUserMessage(object message);
         Task SendCustomUserMessage(object message);
+
+
+        Task ReceiveMessage(object message);
+
+        /// <summary>
+        /// 发送消息给指定用户(系统)
+        /// </summary>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        Task SendSystemToUser(string message);
+
+        /// <summary>
+        /// 发送消息给所有用户(系统)
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        Task SendSystemToAllUser(string message);
     }
     }
 }
 }

+ 4 - 0
OASystem/OASystem.Api/OAMethodLib/SignalR/HubService/CommonService.cs

@@ -14,6 +14,10 @@
             return $"Hello {new Random().Next(0, 100)} {data} ";
             return $"Hello {new Random().Next(0, 100)} {data} ";
         }
         }
 
 
+        internal object ReceiveMessage(string data)
+        {
+            return $"{data}";
+        }
 
 
     }
     }
 }
 }

+ 56 - 9
OASystem/OASystem.Api/OAMethodLib/SignalR/Hubs/ChatHub.cs

@@ -1,8 +1,11 @@
 using Microsoft.AspNetCore.SignalR;
 using Microsoft.AspNetCore.SignalR;
+using NPOI.SS.Formula.Functions;
 using OASystem.API.OAMethodLib.Hub;
 using OASystem.API.OAMethodLib.Hub;
 using OASystem.API.OAMethodLib.Hub.HubClients;
 using OASystem.API.OAMethodLib.Hub.HubClients;
 using OASystem.API.OAMethodLib.SignalR.Hubs;
 using OASystem.API.OAMethodLib.SignalR.Hubs;
 using OASystem.API.OAMethodLib.SignalR.HubService;
 using OASystem.API.OAMethodLib.SignalR.HubService;
+using Quartz;
+using SqlSugar.DistributedSystem.Snowflake;
 using System.DirectoryServices.Protocols;
 using System.DirectoryServices.Protocols;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using static OASystem.API.OAMethodLib.Hub.Hubs.ChatHub;
 using static OASystem.API.OAMethodLib.Hub.Hubs.ChatHub;
@@ -10,6 +13,8 @@ using static OASystem.API.OAMethodLib.JWTHelper;
 
 
 namespace OASystem.API.OAMethodLib.Hub.Hubs
 namespace OASystem.API.OAMethodLib.Hub.Hubs
 {
 {
+    //[Authorize]
+    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
     public class ChatHub : Hub<IChatClient>
     public class ChatHub : Hub<IChatClient>
     {
     {
         private readonly ILogger<ChatHub> _logger;
         private readonly ILogger<ChatHub> _logger;
@@ -33,6 +38,8 @@ namespace OASystem.API.OAMethodLib.Hub.Hubs
         {
         {
             string connid = Context.ConnectionId;
             string connid = Context.ConnectionId;
             string result = $"[{connid}]";
             string result = $"[{connid}]";
+            string userId1 = Context.UserIdentifier;
+
             if (!UserStore.OnlineUser.Exists(u => u.ConnectionId == connid))
             if (!UserStore.OnlineUser.Exists(u => u.ConnectionId == connid))
             {
             {
                 result += "上线成功!" ;
                 result += "上线成功!" ;
@@ -52,9 +59,36 @@ namespace OASystem.API.OAMethodLib.Hub.Hubs
         /// <returns></returns>
         /// <returns></returns>
         public override Task OnConnectedAsync()
         public override Task OnConnectedAsync()
         {
         {
-            var connid = Context.ConnectionId;
-            _logger.LogInformation($"Client ConnectionId=> [[{connid}]] Already Connection Server!");
-            
+            var httpContext = Context.GetHttpContext();
+
+            if (httpContext != null)
+            {
+                string token = httpContext.Request.Headers["Authorization"]; // 根据实际情况修改 header key
+
+                // 处理 token...
+                if (!string.IsNullOrEmpty(token))
+                {
+                    TokenModelJwt tokenModelJwt = JwtHelper.SerializeJwt(token.ToString().Split(" ")[1]);
+                    string result = "";
+                    if (tokenModelJwt != null)
+                    {
+                        var connId = Context.ConnectionId;
+
+                        UserStore.OnlineUser.Add(new UserModel() { UserId = tokenModelJwt.UserId, ConnectionId = connId, GroupName = "FMGJ-OASystem" });
+
+                        _logger.LogInformation($"Client ConnectionId=> [[{connId}]] UserId=> [[{tokenModelJwt.UserId}]] Already Connection Server!");
+
+                        //Clients.All.SendAsync("GetOnlineResponse", $"[{tokenModelJwt.UserName}({tokenModelJwt.Role})] 上线");
+
+                        Clients.Clients(connId).ReceiveMessage(_common.ReceiveMessage($"[{tokenModelJwt.UserName}({tokenModelJwt.Role})] 已上线!"));
+                        //
+                    }
+                }
+            }
+
+            //给当前连接返回消息
+            //await Clients.Client(connid).SendAsync("SignalRLoginResponse", result);
+
             return base.OnConnectedAsync();
             return base.OnConnectedAsync();
         }
         }
 
 
@@ -65,16 +99,16 @@ namespace OASystem.API.OAMethodLib.Hub.Hubs
         /// <returns></returns>
         /// <returns></returns>
         public override Task OnDisconnectedAsync(Exception exception)
         public override Task OnDisconnectedAsync(Exception exception)
         {
         {
-            var connid = Context.ConnectionId;
-            _logger.LogInformation($"Client ConnectionId=> [[{connid}]] Already Close Connection Server!");
-            var model = UserStore.OnlineUser.Find(u => u.ConnectionId == connid);
-            int count = UserStore.OnlineUser.RemoveAll(u => u.ConnectionId == connid);
+            var connId = Context.ConnectionId;
+            _logger.LogInformation($"Client ConnectionId=> [[{connId}]] Already Close Connection Server!");
+            var model = UserStore.OnlineUser.Find(u => u.ConnectionId == connId);
+            int count = UserStore.OnlineUser.RemoveAll(u => u.ConnectionId == connId);
             if (model != null)
             if (model != null)
             {
             {
 
 
                 var onlineUser = UserStore.OnlineUser.FindAll(u => u.GroupName == model.GroupName);
                 var onlineUser = UserStore.OnlineUser.FindAll(u => u.GroupName == model.GroupName);
 
 
-                Clients.Group(model.GroupName).SendAsync("GetUsersResponse", onlineUser);
+                Clients.Clients(connId).ReceiveMessage(_common.ReceiveMessage($"[UserID=>{model.UserId} ConnectionId=> {model.ConnectionId} ] 已下线!"));
             }
             }
             return base.OnDisconnectedAsync(exception);
             return base.OnDisconnectedAsync(exception);
         }
         }
@@ -94,7 +128,20 @@ namespace OASystem.API.OAMethodLib.Hub.Hubs
             await Clients.Caller.SendAll(_common.SendCaller(data));
             await Clients.Caller.SendAll(_common.SendCaller(data));
         }
         }
 
 
+        /// <summary>
+        /// 发送消息给指定用户(系统)
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        public async Task SendSystemToUser(string id, string message) => await Clients.Client(id).SendAsync("ReceiveMessage", message);
 
 
-        
+        /// <summary>
+        /// 发送消息给所有用户(系统)
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        public async Task SendSystemToAllUser(string message) => await Clients.All.SendAsync("ReceiveMessage", message);
     }
     }
 }
 }

+ 0 - 1
OASystem/OASystem.Api/OAMethodLib/SignalR/Hubs/UserStore.cs

@@ -6,7 +6,6 @@
 
 
     }
     }
 
 
-
     public class UserModel
     public class UserModel
     {
     {
         public int UserId { get; set; }
         public int UserId { get; set; }

+ 35 - 2
OASystem/OASystem.Api/Program.cs

@@ -54,8 +54,7 @@ builder.Services.AddControllers()
         //options.JsonSerializerOptions.Converters.Add(new JsonConverterDecimal(0.0000M));
         //options.JsonSerializerOptions.Converters.Add(new JsonConverterDecimal(0.0000M));
     });
     });
 
 
-//// 添加授权服务
-//builder.Services.AddMyJWTBearerAuth();
+builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 
 
 #region Cors
 #region Cors
 builder.Services.AddCors(policy =>
 builder.Services.AddCors(policy =>
@@ -68,6 +67,7 @@ builder.Services.AddCors(policy =>
 
 
     policy.AddPolicy("Cors", opt => opt
     policy.AddPolicy("Cors", opt => opt
           .SetIsOriginAllowed(origin => true)//这个必须加
           .SetIsOriginAllowed(origin => true)//这个必须加
+          //.AllowAnyOrigin()
           .AllowAnyHeader()
           .AllowAnyHeader()
           .WithMethods("GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS")
           .WithMethods("GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS")
           .AllowCredentials());//这个一定不能少);
           .AllowCredentials());//这个一定不能少);
@@ -228,6 +228,39 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                 ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
                 ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
                 RequireExpirationTime = true,
                 RequireExpirationTime = true,
             };
             };
+            options.Events = new JwtBearerEvents
+            {
+                OnMessageReceived = context =>
+                {
+                    var path = context.HttpContext.Request.Path;
+                    //如果是signalr请求,需要将token转存,否则JWT获取不到token。OPTIONS请求需要过滤到,因为OPTIONS请求获取不到Token,用NGINX过滤掉OPTION请求.
+                    if (path.StartsWithSegments("/ChatHub"))
+                    {
+                        string accessToken = context.Request.Query["access_token"].ToString();
+                        if (string.IsNullOrWhiteSpace(accessToken))
+                        {
+                            accessToken = context.Request.Headers["Authorization"].ToString();
+                        }
+                        context.Token = accessToken.Replace("Bearer ", "").Trim();
+                    }
+                    return Task.CompletedTask;
+                }
+            };
+
+            //options.Events = new JwtBearerEvents
+            //{
+            //    OnMessageReceived = context =>
+            //    {
+            //        // 当我们收到消息时,去获取请求中的access_token字段
+            //        var accessToken = context.Request.Query["access_token"];
+            //        // 如果没有就去头上找,找到了就放入我们context.token中
+            //        if (!string.IsNullOrEmpty(accessToken))
+            //        {
+            //            context.Token = accessToken;
+            //        }
+            //        return Task.CompletedTask;
+            //    }
+            //};
         });
         });
 #endregion
 #endregion
 
 

+ 23 - 0
OASystem/OASystem.Domain/Dtos/System/MsgDto.cs

@@ -18,6 +18,29 @@ namespace OASystem.Domain.Dtos.System
         public int UserId { get; set; }
         public int UserId { get; set; }
     }
     }
 
 
+    /// <summary>
+    /// 消息类型
+    /// 请求dto
+    /// </summary>
+    public class MsgTypeDto : PortDtoBase
+    {
+        /// <summary>
+        /// 用户ID
+        /// </summary>
+        public int UserId { get; set; }
+    }
+
+    public class PotsMessagePageListDto : DtoBase
+    {
+        /// <summary>
+        /// 消息类型
+        /// 1 团组操作通知 2 任务操作通知
+        /// </summary>
+        public int Type { get; set; }
+
+        public int UserId { get; set; }
+    }
+
     /// <summary>
     /// <summary>
     /// 消息详细信息
     /// 消息详细信息
     /// 请求dto
     /// 请求dto

+ 14 - 0
OASystem/OASystem.Domain/ViewModels/System/MessageView.cs

@@ -128,4 +128,18 @@ namespace OASystem.Domain.ViewModels.System
         /// </summary>
         /// </summary>
         public DateTime ReadTime { get; set; }
         public DateTime ReadTime { get; set; }
     }
     }
+
+    public class MessageTypeView 
+    {
+
+        public int Id { get; set; }
+        /// <summary>
+        /// 分类名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 未读条数
+        /// </summary>
+        public int UnReadCount { get; set; } = 0;
+    }
 }
 }

+ 92 - 18
OASystem/OASystem.Infrastructure/Repositories/System/MessageRepository.cs

@@ -1,4 +1,5 @@
-using NPOI.POIFS.Crypt.Dsig;
+using Newtonsoft.Json;
+using NPOI.POIFS.Crypt.Dsig;
 using NPOI.SS.Formula.Functions;
 using NPOI.SS.Formula.Functions;
 using OASystem.Domain;
 using OASystem.Domain;
 using OASystem.Domain.Dtos.System;
 using OASystem.Domain.Dtos.System;
@@ -15,7 +16,15 @@ namespace OASystem.Infrastructure.Repositories.System
 {
 {
     public class MessageRepository : BaseRepository<Sys_Message, MessageView>
     public class MessageRepository : BaseRepository<Sys_Message, MessageView>
     {
     {
-        public MessageRepository(SqlSugarClient sqlSugar) : base(sqlSugar) { }
+        private readonly SetDataRepository _setData; 
+        private readonly List<int> _operationTypeList = new List<int>() { 1, 2, 3, 4, 5 }; //操作通知所属类型
+        private readonly List<int> _taskTypeList = new List<int>() { 6 };//任务通知 TaskNotification
+
+        public MessageRepository(SqlSugarClient sqlSugar, SetDataRepository setData) 
+            : base(sqlSugar) 
+        { 
+            _setData = setData;
+        }
 
 
         /// <summary>
         /// <summary>
         /// 发布消息
         /// 发布消息
@@ -121,36 +130,36 @@ namespace OASystem.Infrastructure.Repositories.System
                     
                     
                     //操作通知 OperationNotification
                     //操作通知 OperationNotification
                     List<int> operationTypeList = new List<int>() {1,2,3,4,5 };
                     List<int> operationTypeList = new List<int>() {1,2,3,4,5 };
-                    var operationNotificatioData = _readableMsgList.Where(it => operationTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
-                    int operationNotificatioDataCount = operationNotificatioData.Count;
+                    var operationNotificationData = _readableMsgList.Where(it => operationTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
+                    int operationNotificationDataCount = operationNotificationData.Count;
                     // 计算起始索引和结束索引
                     // 计算起始索引和结束索引
                     int operationStartIndex = (currentPage - 1) * pageSize;
                     int operationStartIndex = (currentPage - 1) * pageSize;
-                    int operationEndIndex = Math.Min(operationStartIndex + pageSize, operationNotificatioDataCount);
+                    int operationEndIndex = Math.Min(operationStartIndex + pageSize, operationNotificationDataCount);
 
 
-                    var operationNotificatioDataView = new {
-                        Count = operationNotificatioDataCount,
-                        UnReadCount = operationNotificatioData.Where(it => it.IsRead == 0).Count(),
-                        OperationNotificatioData = operationNotificatioData.Skip(operationStartIndex).Take(pageSize).ToList()
+                    var operationNotificationDataView = new {
+                        Count = operationNotificationDataCount,
+                        UnReadCount = operationNotificationData.Where(it => it.IsRead == 0).Count(),
+                        OperationNotificatioData = operationNotificationData.Skip(operationStartIndex).Take(pageSize).ToList()
                     };
                     };
 
 
                     //任务通知 TaskNotification
                     //任务通知 TaskNotification
                     List<int> taskTypeList = new List<int>() { 6 };
                     List<int> taskTypeList = new List<int>() { 6 };
-                    var taskNotificatioData = _readableMsgList.Where(it => taskTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
-                    int taskNotificatioDataCount = taskNotificatioData.Count;
+                    var taskNotificationData = _readableMsgList.Where(it => taskTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
+                    int taskNotificationDataCount = taskNotificationData.Count;
                     // 计算起始索引和结束索引
                     // 计算起始索引和结束索引
                     int taskStartIndex = (currentPage - 1) * pageSize;
                     int taskStartIndex = (currentPage - 1) * pageSize;
-                    int taskEndIndex = Math.Min(operationStartIndex + pageSize, operationNotificatioDataCount);
+                    int taskEndIndex = Math.Min(taskStartIndex + pageSize, taskNotificationDataCount);
 
 
-                    var taskNotificatioDataView = new
+                    var taskNotificationDataView = new
                     {
                     {
-                        Count = taskNotificatioDataCount,
-                        UnReadCount = taskNotificatioData.Where(it => it.IsRead == 0).Count(),
-                        TaskNotificatioData = taskNotificatioData.Skip(taskStartIndex).Take(pageSize).ToList()
+                        Count = taskNotificationDataCount,
+                        UnReadCount = taskNotificationData.Where(it => it.IsRead == 0).Count(),
+                        TaskNotificationData = taskNotificationData.Skip(taskStartIndex).Take(pageSize).ToList()
                     };
                     };
 
 
                     var _view = new {
                     var _view = new {
-                        OperationNotificatio = operationNotificatioDataView,
-                        TaskNotificatio = taskNotificatioDataView
+                        OperationNotification = operationNotificationDataView,
+                        TaskNotification = taskNotificationDataView
                     };
                     };
 
 
                     result.Code = 0;
                     result.Code = 0;
@@ -166,6 +175,71 @@ namespace OASystem.Infrastructure.Repositories.System
             return result;
             return result;
         }
         }
 
 
+
+        /// <summary>
+        /// 获取消息列表
+        /// </summary>
+        /// <param name="uId">可读用户Id</param>
+        /// <returns></returns>
+        public async Task<Result> PotsMsgTypeData(MsgTypeDto dto)
+        {
+            Result result = new Result() { Code = -1, Msg = "未知错误", Data = null };
+
+            if (dto.PortType == 1 || dto.PortType == 2 || dto.PortType == 3)  // web/android
+            {
+
+                var msgTypeResult = await _setData.GetSetDataBySTId(_setData, 77);
+                if (msgTypeResult.Code != 0)
+                {
+                    result.Msg = "消息类型不存在!";
+                    return result;
+                }
+                string msgTypeDataStr = JsonConvert.SerializeObject(msgTypeResult.Data);
+                var msgTypeData = JsonConvert.DeserializeObject<List<MessageTypeView>>(msgTypeDataStr);
+
+                string msgSqlWhere = string.Format(@"Select sm.Id,sm.Type,sm.Title,sm.Content,sd.DepName issuerDep,su.CnName issuerUser, 
+                                                            sm.ReleaseTime,smra.Id AuthId,smra.ReadableUId,smra.IsRead,smra.ReadTime 
+                                                     From Sys_Message sm 
+                                                     Inner Join Sys_MessageReadAuth smra On sm.Id = smra.MsgId
+                                                     Inner Join Sys_Users su On sm.IssuerId = su.Id
+                                                     Inner Join Sys_Department sd On su.DepId = sd.Id
+                                                     Inner Join Sys_Users suAuth On smra.ReadableUId = suAuth.Id
+                                                     Where sm.IsDel = 0
+                                                     And smra.IsDel = 0 
+                                                     And smra.ReadableUId = {0}
+                                                     Order By ReleaseTime Desc ", dto.UserId);
+                var _readableMsgList = await _sqlSugar.SqlQueryable<ReadbleMessageView>(msgSqlWhere).ToListAsync();
+                if (_readableMsgList.Count > 0)
+                {
+                    //操作通知 OperationNotification
+                    var operationNotificationData = _readableMsgList.Where(it => _operationTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
+                    int operationNotificationDataCount = operationNotificationData.Count;
+                   
+                    //任务通知
+                    var taskNotificationData = _readableMsgList.Where(it => _taskTypeList.Contains(it.Type)).OrderBy(it => it.IsRead).ToList();
+                    int taskNotificationDataCount = taskNotificationData.Count;
+
+                    foreach (var item in msgTypeData)
+                    {
+                        //1021	团组操作通知 1020	任务操作通知
+                        if (item.Id == 1020) item.UnReadCount = operationNotificationDataCount;
+                        else if (item.Id == 1021) item.UnReadCount = taskNotificationDataCount;
+                    }
+
+                    result.Code = 0;
+                    result.Msg = "成功!";
+                    result.Data = msgTypeData;
+                }
+                else
+                {
+                    result.Msg = "暂无该用户相关消息!";
+                }
+            }
+
+            return result;
+        }
+
+
         /// <summary>
         /// <summary>
         /// 获取消息未读消息条数
         /// 获取消息未读消息条数
         /// </summary>
         /// </summary>