Переглянути джерело

任务 318 市州通用-【补充工单】功能

tangjiang 2 місяців тому
батько
коміт
9c37e4585d

+ 77 - 3
src/Hotline.Api/Controllers/OrderController.cs

@@ -77,6 +77,10 @@ using XF.Domain.Repository;
 using XF.Utility.EnumExtensions;
 using OrderDto = Hotline.Share.Dtos.Order.OrderDto;
 using System.Threading;
+using Hotline.Realtimes;
+using Hotline.Article;
+using Hotline.Share.Dtos.Article;
+using Hotline.Api.Realtimes;
 
 namespace Hotline.Api.Controllers;
 
@@ -158,6 +162,8 @@ public class OrderController : BaseController
     private readonly IRepository<SystemDicData> _sysDicDataRepository;
     private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
     private readonly IRepository<OrderComplement> _orderComplementRepository;
+    private readonly IRealtimeService _realtimeService;
+    private readonly IRepository<NotificationWaitSend> _notificationWaitSendRepository;
 
     public OrderController(
         IOrderDomainService orderDomainService,
@@ -231,7 +237,9 @@ public class OrderController : BaseController
         IOrderSnapshotApplication orderSnapshotApplication,
         IRepository<SystemDicData> sysDicDataRepository,
         IRepository<SystemOrganize> systemOrganizeRepository,
-        IRepository<OrderComplement> orderComplementRepository)
+        IRepository<OrderComplement> orderComplementRepository,
+        IRealtimeService realtimeService,
+        IRepository<NotificationWaitSend> notificationWaitSendRepository)
     {
         _orderDomainService = orderDomainService;
         _orderRepository = orderRepository;
@@ -305,6 +313,8 @@ public class OrderController : BaseController
         _sysDicDataRepository = sysDicDataRepository;
         _systemOrganizeRepository = systemOrganizeRepository;
         _orderComplementRepository = orderComplementRepository;
+        _realtimeService = realtimeService;
+        _notificationWaitSendRepository = notificationWaitSendRepository;
     }
 
     #endregion
@@ -8951,7 +8961,7 @@ public class OrderController : BaseController
 
     #region 添加补充
     /// <summary>
-    /// 添加补充
+    /// 添加补充 _notificationWaitSendRepository
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
@@ -8978,7 +8988,71 @@ public class OrderController : BaseController
             IsProComplement = false
         };
 
-        await _orderComplementRepository.AddAsync(complement, HttpContext.RequestAborted);
+        var id = await _orderComplementRepository.AddAsync(complement, HttpContext.RequestAborted);
+        if (!string.IsNullOrEmpty(id))
+        {
+            //获取当前办理节点数据
+            var work = await _workflowStepRepository.GetAsync(p => p.Id == data.ActualHandleStepId, HttpContext.RequestAborted);
+            if (work != null)
+            {
+                //获取办理指定类型
+                var workflowStepHandler = work.GetWorkflowStepHandler();
+                if (workflowStepHandler != null)
+                {
+                    List<string> users = [];
+                    if (!string.IsNullOrEmpty(workflowStepHandler.UserId)) //指定用户
+                    {
+                        users.Add(workflowStepHandler.UserId);
+                    }
+                    else if (!string.IsNullOrEmpty(workflowStepHandler.RoleId))//指定角色
+                    {
+                        //查询指定角色下面所有的用户
+                        var userlist = await _userRepository.Queryable().Where(x =>
+                            x.OrgId == workflowStepHandler.OrgId && x.Roles.Any(d => workflowStepHandler.RoleId.Contains(d.Id))).Select(p => p.Id).ToListAsync();
+                        if (userlist != null && userlist.Count > 0)
+                            users.AddRange(userlist);
+                    }
+                    else if (!string.IsNullOrEmpty(workflowStepHandler.OrgId))//指定部门
+                    {
+                        //添加成功以后查询需要发送的人员信息
+                        var acceptSmsRoleIds = _systemSettingCacheManager.GetSetting(SettingConstants.AcceptSmsRoleIds)?.SettingValue;
+
+                        //查询指定部门下面经办人的信息
+                        var userlist = await _userRepository.Queryable().Where(x =>
+                            x.OrgId == workflowStepHandler.OrgId && x.Roles.Any(d => acceptSmsRoleIds.Contains(d.Id))).Select(p => p.Id).ToListAsync();
+                        if (userlist != null && userlist.Count > 0)
+                            users.AddRange(userlist);
+                    }
+                    if (users != null && users.Count > 0)
+                    {
+                        var msg = @"工单" + data.No + "有补充内容,请注意查收!";
+                        foreach (var item in users)
+                        {
+                            //发送消息
+                            await _realtimeService.OrderComplementAsync(item, msg, HttpContext.RequestAborted);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// 根据userid查询补充消息
+    /// </summary>
+    /// <param name="userId"></param>
+    /// <returns></returns>
+    [HttpGet("get_notification_wait_send/{userId}")]
+    public async Task<List<NotificationWaitSendDto>> GetNotificationWaitSend(string userId)
+    {
+        var data = await _notificationWaitSendRepository.Queryable()
+                .Where(p => p.UserId == userId && p.Method == RealtimeMethods.OrderComplementRecord)
+                .ToListAsync();
+        if (data != null && data.Count > 0)
+        {
+            await _notificationWaitSendRepository.RemoveRangeAsync(data, HttpContext.RequestAborted);
+        }
+        return _mapper.Map<List<NotificationWaitSendDto>>(data);
     }
     #endregion
 }

+ 50 - 26
src/Hotline.Api/Realtimes/RealtimeService.cs

@@ -1,4 +1,5 @@
-using Hotline.Article;
+using DocumentFormat.OpenXml.Spreadsheet;
+using Hotline.Article;
 using Hotline.Caching.Interfaces;
 using Hotline.Caching.Services;
 using Hotline.Realtimes;
@@ -18,17 +19,20 @@ public class RealtimeService : IRealtimeService, IScopeDependency
     private readonly IRealtimeCacheManager _realtimeCacheManager;
     private readonly IRepository<CircularRecord> _circularRecordRepository;
     private readonly IRepository<User> _userRepository;
+    private readonly IRepository<NotificationWaitSend> _notificationWaitSendRepository;
 
     public RealtimeService(
         IHubContext<HotlineHub> hubContext,
         IRealtimeCacheManager realtimeCacheManager,
         IRepository<CircularRecord> circularRecordRepository,
-        IRepository<User> userRepository)
+        IRepository<User> userRepository,
+        IRepository<NotificationWaitSend> notificationWaitSendRepository)
     {
         _hubContext = hubContext;
         _realtimeCacheManager = realtimeCacheManager;
         _circularRecordRepository = circularRecordRepository;
         _userRepository = userRepository;
+        _notificationWaitSendRepository = notificationWaitSendRepository;
     }
 
     #region 通讯通知
@@ -123,14 +127,34 @@ public class RealtimeService : IRealtimeService, IScopeDependency
     #endregion
 
     /// <summary>
-    /// 工单补充消息通知
+    /// 工单补充消息通知 
     /// </summary>
     /// <param name="userId"></param>
     /// <param name="msg"></param>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
-    public Task OrderComplementAsync(string userId, string msg, CancellationToken cancellationToken) =>
-        SendToUserAsync(userId, RealtimeMethods.OrderComplementRecord, msg, cancellationToken);
+    public async Task OrderComplementAsync(string userId, string msg, CancellationToken cancellationToken)
+    {
+        var connection = await _realtimeCacheManager.GetConnectionOtherAsync(userId, cancellationToken);
+        if (connection == null)
+        {
+            //如果没有建立链接,写入数据库
+            NotificationWaitSend notificationWait = new NotificationWaitSend()
+            {
+                UserId = userId,
+                Msg = msg,
+                Method = RealtimeMethods.OrderComplementRecord,
+                State = "0"
+            };
+            await _notificationWaitSendRepository.AddAsync(notificationWait, cancellationToken);
+        }
+        else
+        {
+            //如果建立了链接直接发消息
+            await _hubContext.Clients.Client(connection.ConnectionId).SendAsync(RealtimeMethods.OrderComplementRecord, msg, cancellationToken);
+        }
+    }
+
 
     #region 系统信息通知
 
@@ -162,7 +186,7 @@ public class RealtimeService : IRealtimeService, IScopeDependency
                 {
                     await SendToUserAsync(user.Id, RealtimeMethods.CircularRecord,
                         new CircularRecoordDto()
-                            { CircularType = Share.Enums.Article.ECircularType.Org, Count = record.RecordCount },
+                        { CircularType = Share.Enums.Article.ECircularType.Org, Count = record.RecordCount },
                         cancellationToken);
                 }
                 catch
@@ -176,37 +200,37 @@ public class RealtimeService : IRealtimeService, IScopeDependency
 
     #region 大屏.数据展示
 
-    public Task BsDataShowChanged1Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged1Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea1, obj, cancellationToken);
-    public Task BsDataShowChanged2Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged2Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea2, obj, cancellationToken);
-    public Task BsDataShowChanged3Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged3Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea3, obj, cancellationToken);
-    public Task BsDataShowChanged4Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged4Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea4, obj, cancellationToken);
-    public Task BsDataShowChanged5Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged5Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea5, obj, cancellationToken);
-    public Task BsDataShowChanged6Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged6Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea6, obj, cancellationToken);
-    public Task BsDataShowChanged7Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged7Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea7, obj, cancellationToken);
-    public Task BsDataShowChanged8Async(object obj, CancellationToken cancellationToken) => 
+    public Task BsDataShowChanged8Async(object obj, CancellationToken cancellationToken) =>
         SendToGroupAsync(RealtimeGroupNames.BigScreenDataShow, RealtimeMethods.BsDataShowArea8, obj, cancellationToken);
 
-	#endregion
+    #endregion
 
-	#region 大屏坐席数据
-	public Task BsSeatStateDataShowChangedAsync1(object obj, CancellationToken cancellationToken) =>
-		SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea1, obj, cancellationToken);
+    #region 大屏坐席数据
+    public Task BsSeatStateDataShowChangedAsync1(object obj, CancellationToken cancellationToken) =>
+        SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea1, obj, cancellationToken);
 
-	public Task BsSeatStateDataShowChangedAsync2(object obj, CancellationToken cancellationToken) =>
-		SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea2, obj, cancellationToken);
+    public Task BsSeatStateDataShowChangedAsync2(object obj, CancellationToken cancellationToken) =>
+        SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea2, obj, cancellationToken);
 
-	public Task BsSeatStateDataShowChangedAsync3(object obj, CancellationToken cancellationToken) =>
-		SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea3, obj, cancellationToken);
+    public Task BsSeatStateDataShowChangedAsync3(object obj, CancellationToken cancellationToken) =>
+        SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea3, obj, cancellationToken);
 
-	public Task BsSeatStateDataShowChangedAsync4(object obj, CancellationToken cancellationToken) =>
-		SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea4, obj, cancellationToken);
+    public Task BsSeatStateDataShowChangedAsync4(object obj, CancellationToken cancellationToken) =>
+        SendToGroupAsync(RealtimeGroupNames.BigScreenSeatState, RealtimeMethods.BsSeatStateDataShowArea4, obj, cancellationToken);
     #endregion
 
     #region 数据大屏
@@ -227,7 +251,7 @@ public class RealtimeService : IRealtimeService, IScopeDependency
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
     public Task OrderHandlingDetailAsync(object obj, CancellationToken cancellationToken) =>
-        SendToGroupAsync(RealtimeGroupNames.BigDataScreen, RealtimeMethods.OrderHandlingDetail,obj, cancellationToken);
+        SendToGroupAsync(RealtimeGroupNames.BigDataScreen, RealtimeMethods.OrderHandlingDetail, obj, cancellationToken);
 
     /// <summary>
     /// 推送二次办理中工单概览
@@ -292,6 +316,6 @@ public class RealtimeService : IRealtimeService, IScopeDependency
 
     #endregion
 
-   
+
 
 }

+ 18 - 0
src/Hotline.Share/Dtos/Article/NotificationWaitSendDto.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Dtos.Article
+{
+    public class NotificationWaitSendDto
+    {
+        public string Id { get; set; }
+
+        public string Msg { get; set; }
+
+        public string? Method { get; set; }
+
+    }
+}

+ 21 - 0
src/Hotline/Article/NotificationWaitSend.cs

@@ -0,0 +1,21 @@
+using XF.Domain.Repository;
+
+namespace Hotline.Article
+{
+    /// <summary>
+    /// 消息待推送
+    /// </summary>
+    public class NotificationWaitSend : CreationEntity
+    {
+        public string UserId { get; set; }
+
+        public string Msg { get; set; }
+
+        public string? Method { get; set; }
+
+        /// <summary>
+        /// 0:待发,1:已发
+        /// </summary>
+        public string? State { get; set; }
+    }
+}

+ 2 - 0
src/Hotline/Caching/Interfaces/IRealtimeCacheManager.cs

@@ -12,5 +12,7 @@ namespace Hotline.Caching.Interfaces
         Task<RealtimeConnection> GetConnectionAsync(string userId, CancellationToken cancellationToken);
 
         Task<bool> IsInGroupAsync(string useId, string groupName, CancellationToken cancellationToken);
+
+        Task<RealtimeConnection> GetConnectionOtherAsync(string userId, CancellationToken cancellationToken);
     }
 }

+ 5 - 0
src/Hotline/Caching/Services/RealtimeCacheManager.cs

@@ -28,4 +28,9 @@ public class RealtimeCacheManager : IRealtimeCacheManager, IScopeDependency
         var connection = await GetConnectionAsync(useId, cancellationToken);
         return connection.IsInGroup(groupName);
     }
+
+    public async Task<RealtimeConnection> GetConnectionOtherAsync(string userId, CancellationToken cancellationToken)
+    {
+        return await _cacheConnection.GetAsync(userId, cancellationToken);
+    }
 }