Sfoglia il codice sorgente

Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test

xf 1 settimana fa
parent
commit
0b69eb2598

+ 9 - 7
src/Hotline.Api/Controllers/AiController.cs

@@ -683,19 +683,21 @@ namespace Hotline.Api.Controllers
                                         //TODO 记录不满意原因到内容中供人工回访甄别选择不满意原因
                                         if (dto.CallTimes.Value>=1 && orgProcessingResults == null)
                                         {
-                                            orgProcessingResults = new Kv() { Key = "0", Value = "默认满意" };
-                                            aiOrderVisitDetail.OrderVisit.VisitState = EVisitState.Visited;
+                                            orgProcessingResults = new Kv() { Key = "6", Value = "未接通" };
+                                            aiOrderVisitDetail.OrderVisit.VisitState = EVisitState.AiVisitWaitForVisit;
+                                            aiOrderVisitDetail.OrderVisit.IsEffectiveAiVisit = false;
                                             aiOrderVisitDetail.OrderVisit.NowEvaluate = orgProcessingResults;
-                                            x.VisitContent = "智能回访两次未接默认已回访";
-                                            x.Volved = true;
-                                            x.IsContact = true;
+                                            x.VisitContent = "智能回访两次未接";
+                                            //x.Volved = true;
+                                            //x.IsContact = true;
                                             x.OrgProcessingResults = orgProcessingResults;
                                             seatDetail.ForEach(x =>
                                             {
                                                 x.VoiceEvaluate = Share.Enums.Order.EVoiceEvaluate.Satisfied;
-                                                x.SeatEvaluate =  ESeatEvaluate.DefaultSatisfied;
-                                                x.VisitContent = "智能回访两次未接默认已回访";
+                                                x.SeatEvaluate =  ESeatEvaluate.NoConnect;
+                                                x.VisitContent = "智能回访两次未接";
                                             });
+
                                         }
                                         else
                                         {

+ 72 - 0
src/Hotline.Api/Controllers/Bi/BiCallController.cs

@@ -29,6 +29,7 @@ using Hotline.Application.StatisticalReport.CallReport;
 using DocumentFormat.OpenXml.Spreadsheet;
 using DocumentFormat.OpenXml.Wordprocessing;
 using NPOI.SS.Formula.Functions;
+using static System.Runtime.InteropServices.JavaScript.JSType;
 
 namespace Hotline.Api.Controllers.Bi;
 
@@ -470,6 +471,77 @@ public class BiCallController : BaseController
             "坐席话务统计分析明细");
     }
 
+    /// <summary>
+    /// 小休统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpGet("restsday")]
+    [AllowAnonymous]
+    public async Task<IReadOnlyList<BiSeatRestDto>> QuerySeatRestDay([FromQuery] QuerySeatRestRequest dto)
+    {
+        return await _telRestRepository.Queryable()
+            .WhereIF(!string.IsNullOrEmpty(dto.UserName), x => x.UserName.Contains(dto.UserName))
+            .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), x => x.StaffNo.Contains(dto.StaffNo))
+            .Where(x => x.CreationTime >= dto.StartTime)
+            .Where(x => x.CreationTime <= dto.EndTime)
+            .GroupBy(x => new { DayTime = x.CreationTime.ToString("yyyy-MM-dd"), x.UserId, x.StaffNo, x.UserName })
+            .Select(x => new BiSeatRestDto
+            {
+                DayTime= x.CreationTime.ToString("yyyy-MM-dd"),
+                UserId = x.UserId,
+                StaffNo = x.StaffNo,
+                UserName = x.UserName,
+                RestCount = SqlFunc.AggregateCount(x.Id),
+                RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
+                CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
+            })
+            .OrderByIF(dto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
+            .OrderByIF(dto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
+            .MergeTable()
+            .ToListAsync(HttpContext.RequestAborted);
+    }
+
+    /// <summary>
+    /// 小休统计
+    /// </summary>
+    /// <param name="dto"></param>
+    /// <returns></returns>
+    [HttpPost("restsday/export")]
+    [LogFilterAlpha("导出日志")]
+    public async Task<FileStreamResult> QuerySeatRestDayExport([FromBody] ExportExcelDto<QuerySeatRestRequest> dto)
+    {
+        var query = await _telRestRepository.Queryable()
+            .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.UserName), x => x.UserName.Contains(dto.QueryDto.UserName))
+            .WhereIF(!string.IsNullOrEmpty(dto.QueryDto.StaffNo), x => x.StaffNo.Contains(dto.QueryDto.StaffNo))
+            .Where(x => x.CreationTime >= dto.QueryDto.StartTime)
+            .Where(x => x.CreationTime <= dto.QueryDto.EndTime)
+             .GroupBy(x => new { DayTime = x.CreationTime.ToString("yyyy-MM-dd"), x.UserId, x.StaffNo, x.UserName })
+            .Select(x => new BiSeatRestDto
+            {
+                DayTime = x.CreationTime.ToString("yyyy-MM-dd"),
+                UserId = x.UserId,
+                StaffNo = x.StaffNo,
+                UserName = x.UserName,
+                RestCount = SqlFunc.AggregateCount(x.Id),
+                RestDuration = SqlFunc.AggregateSum(x.RestDuration / 60) / SqlFunc.AggregateCount(x.Id),
+                CumulativeDuration = SqlFunc.AggregateSum(x.RestDuration / 60)
+            })
+            .OrderByIF(dto.QueryDto.SortRule is 0, a => a.RestDuration, OrderByType.Asc)
+            .OrderByIF(dto.QueryDto.SortRule is 1, a => a.RestDuration, OrderByType.Desc)
+            .MergeTable()
+            .ToListAsync(HttpContext.RequestAborted);
+
+        dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<BiSeatRestDto>(dto.ColumnInfos);
+
+        var dtos = _mapper.Map<ICollection<BiSeatRestDto>>(query)
+                          .Select(stu => _mapper.Map(stu, typeof(BiSeatRestDto), dynamicClass))
+                          .Cast<object>()
+                          .ToList();
+
+        var stream = ExcelHelper.CreateStream(dtos);
+        return ExcelStreamResult(stream, "座席小休统计表");
+    }
 
     /// <summary>
     /// 小休统计

+ 4 - 0
src/Hotline.Api/Controllers/IPPbxController.cs

@@ -987,6 +987,10 @@ namespace Hotline.Api.Controllers
             {
                 actionType = actionType.Where(m => new int[] { 4, 5 }.Contains(m.Key) == false).ToList();
             }
+            if (_appOptions.Value.IsLuZhou)// 542 取消【坐席动作类型统计】列表中话后整理的选项。
+			{
+				actionType = actionType.Where(m => new int[] { 1 }.Contains(m.Key) == false).ToList();
+			}
             return new
             {
                 ActionType = actionType,

+ 34 - 21
src/Hotline.Api/Controllers/KnowledgeCommonController.cs

@@ -1,4 +1,5 @@
 using Hotline.Application.Knowledge;
+using Hotline.Configurations;
 using Hotline.KnowledgeBase;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Settings;
@@ -11,6 +12,7 @@ using Hotline.Share.Requests;
 using Hotline.Tools;
 using MapsterMapper;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Options;
 using SqlSugar;
 using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
@@ -33,26 +35,28 @@ namespace Hotline.Api.Controllers
         private readonly ISystemOrganizeRepository _systemOrganizeRepository;
         private readonly IRepository<Hotspot> _hotspotTypeRepository;
         private readonly IKnowApplication _knowApplication;
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="knowledgeTypeRepository"></param>
-        /// <param name="knowledgeTypeDomainService"></param>
-        /// <param name="knowledgeStandardRepository"></param>
-        /// <param name="sessionContext"></param>
-        /// <param name="mapper"></param>
-        /// <param name="systemOrganizeRepository"></param>
-        /// <param name="hotspotTypeRepository"></param>
-        /// <param name="knowApplication"></param>
-        public KnowledgeCommonController(IRepository<KnowledgeType> knowledgeTypeRepository,
+		private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="knowledgeTypeRepository"></param>
+		/// <param name="knowledgeTypeDomainService"></param>
+		/// <param name="knowledgeStandardRepository"></param>
+		/// <param name="sessionContext"></param>
+		/// <param name="mapper"></param>
+		/// <param name="systemOrganizeRepository"></param>
+		/// <param name="hotspotTypeRepository"></param>
+		/// <param name="knowApplication"></param>
+		public KnowledgeCommonController(IRepository<KnowledgeType> knowledgeTypeRepository,
             IKnowledgeTypeDomainService knowledgeTypeDomainService,
             IRepository<KnowledgeStandard> knowledgeStandardRepository,
             ISessionContext sessionContext,
             IMapper mapper,
             ISystemOrganizeRepository systemOrganizeRepository,
             IRepository<Hotspot> hotspotTypeRepository,
-             IKnowApplication knowApplication)
+             IKnowApplication knowApplication,
+			 IOptionsSnapshot<AppConfiguration> appOptions)
         {
             _knowledgeTypeRepository = knowledgeTypeRepository;
             _knowledgeTypeDomainService = knowledgeTypeDomainService;
@@ -62,7 +66,9 @@ namespace Hotline.Api.Controllers
             _systemOrganizeRepository = systemOrganizeRepository;
             _hotspotTypeRepository = hotspotTypeRepository;
             _knowApplication = knowApplication;
-        }
+			_appOptions = appOptions;
+
+		}
         #endregion
 
         #region 知识分类
@@ -157,6 +163,10 @@ namespace Hotline.Api.Controllers
         [HttpGet("treelist")]
         public async Task<List<KnowledgeTypeDto>> GetTreeList(bool? isEnable, string? attribution, EKnowledgeStatus? status)
         {
+            if (_appOptions.Value.IsLuZhou)
+            {
+                attribution = string.Empty;
+			}
             var isCenter = _sessionContext.OrgIsCenter;
             var query = _knowledgeTypeRepository.Queryable()
                 .WhereIF(isEnable.HasValue, x => x.IsEnable == isEnable);
@@ -209,12 +219,15 @@ namespace Hotline.Api.Controllers
         [HttpGet("treelist/org")]
         public async Task<List<KnowledgeOrgDto>> GetTreeList(string? Attribution)
         {
-
-            //await Db.Queryable<SystemOrganize>()
-            // .Where(it => it.Id.StartsWith(orgCode))
-            // .OrderBy(d => d.Id)
-            // .ToTreeAsync(it => it.Children, it => it.ParentId, orgCode.Length > 6 ? orgCode.Substring(0, orgCode.Length - 3) : null);
-            var orgCode = _sessionContext.RequiredOrgId;
+			if (_appOptions.Value.IsLuZhou)
+			{
+				Attribution = string.Empty;
+			}
+			//await Db.Queryable<SystemOrganize>()
+			// .Where(it => it.Id.StartsWith(orgCode))
+			// .OrderBy(d => d.Id)
+			// .ToTreeAsync(it => it.Children, it => it.ParentId, orgCode.Length > 6 ? orgCode.Substring(0, orgCode.Length - 3) : null);
+			var orgCode = _sessionContext.RequiredOrgId;
             var query = _systemOrganizeRepository.Queryable().WhereIF(!_sessionContext.OrgIsCenter, it => it.Id.StartsWith(_sessionContext.RequiredOrgId))
                     .Select(it => new KnowledgeOrgDto()
                     {

+ 8 - 2
src/Hotline.Api/Controllers/OrderController.cs

@@ -1184,6 +1184,10 @@ public class OrderController : BaseController
     {
         var rsp = new
         {
+            Industry = _systemSettingCacheManager.Snapshot ? await _industryRepository
+                    .Queryable()
+                    .Select(d => new { d.Id, d.Name, }).ToListAsync() 
+                : null,
             ChannelOptions = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel),
             AcceptTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType),
             OrderTags = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.OrderTag)
@@ -5079,7 +5083,8 @@ public class OrderController : BaseController
             var specialNumber = await _specialNumberRepository.GetAsync(p => p.PhoneNumber == dto.FromPhone, HttpContext.RequestAborted);
             if (specialNumber != null)
             {
-                if (specialNumber.PoliticalIdentityValue == "1")
+                var selectPushTypeCode = _systemSettingCacheManager.GetSetting(SettingConstants.SelectPushTypeCode).SettingValue;
+                if (selectPushTypeCode.Contains(specialNumber.PoliticalIdentityValue))
                 {
                     if (dto.OrderPushTypes == null || dto.OrderPushTypes.Count() == 0 || dto.OrderPushTypes.Exists(p => p.PushTypeCode == "9") == false)
                         throw UserFriendlyException.SameMessage("人大代表来电,请选择推送分类人大代表意见快办!");
@@ -5348,7 +5353,8 @@ public class OrderController : BaseController
             var specialNumber = await _specialNumberRepository.GetAsync(p => p.PhoneNumber == dto.FromPhone, HttpContext.RequestAborted);
             if (specialNumber != null)
             {
-                if (specialNumber.PoliticalIdentityValue == "1")
+                var selectPushTypeCode = _systemSettingCacheManager.GetSetting(SettingConstants.SelectPushTypeCode).SettingValue;
+                if (selectPushTypeCode.Contains(specialNumber.PoliticalIdentityValue))
                 {
                     if (dto.OrderPushTypes == null || dto.OrderPushTypes.Count() == 0 || dto.OrderPushTypes.Exists(p => p.PushTypeCode == "9") == false)
                         throw UserFriendlyException.SameMessage("人大代表来电,请选择推送分类人大代表意见快办!");

+ 18 - 1
src/Hotline.Api/Controllers/UserController.cs

@@ -161,7 +161,7 @@ public class UserController : BaseController
     public async Task<PagedDto<UserDto>> QueryPaged([FromQuery] UserPagedDto dto)
     {
         var query =  _userApplication.QueryPaged(dto);
-        Console.WriteLine(query.ToSqlString());
+        //Console.WriteLine(query.ToSqlString());
         var (total, items) = await query.ToPagedListAsync(dto, HttpContext.RequestAborted);
 
         //var (total, items) = await _userRepository.Queryable(includeDeleted: true)
@@ -267,10 +267,27 @@ public class UserController : BaseController
         var user = await _accountRepository.GetAsync(id) ??
             throw UserFriendlyException.SameMessage("用户不存在");
         user.LockoutEnd = null;
+        user.LockoutEnabled = false;
         await _accountRepository.UpdateNullAsync(user, HttpContext.RequestAborted);
         return "解锁成功";
     }
 
+    /// <summary>
+    /// 锁定用户
+    /// </summary>
+    /// <returns></returns>
+    [HttpPut("lockuser")]
+    [LogFilter("锁定用户")]
+    public async Task<string> LockUserAsync([FromQuery] string id)
+    {
+        var user = await _accountRepository.GetAsync(id) ??
+            throw UserFriendlyException.SameMessage("用户不存在");
+        user.LockoutEnd = Convert.ToDateTime("2099-12-31 23:59:59");
+        user.LockoutEnabled = true;
+        await _accountRepository.UpdateNullAsync(user, HttpContext.RequestAborted);
+        return "锁定用户成功";
+    }
+
     /// <summary>
     /// 新增用户
     /// </summary>

+ 2 - 0
src/Hotline.Application/Mappers/IdentityMapperConfigs.cs

@@ -20,6 +20,8 @@ public class IdentityMapperConfigs : IRegister
 
         config.NewConfig<User, UserDto>()
             .IgnoreIf((s, d) => s.Account == null, d => d.UserName)
+            .IgnoreIf((s,d)=> s.Account == null,d=>d.AccountLockoutEnd)
+            .IgnoreIf((s,d)=> s.Account == null,d=>d.AccountLockoutEnabled)
             .IgnoreIf((s, d) => s.Roles == null || !s.Roles.Any(), d => d.RoleNames)
             .IgnoreIf((s, d) => s.Organization == null, d => d.Organization)
             .Map(d => d.UserName, x => x.Account.UserName)

+ 226 - 134
src/Hotline.Application/OrderApp/OrderApplication.cs

@@ -1,8 +1,4 @@
-using DocumentFormat.OpenXml.Drawing.Diagrams;
-using DocumentFormat.OpenXml.Office.CustomUI;
-using DocumentFormat.OpenXml.Office2010.CustomUI;
-using DocumentFormat.OpenXml.Spreadsheet;
-using DotNetCore.CAP;
+using DotNetCore.CAP;
 using FluentValidation;
 using Hotline.Application.FlowEngine;
 using Hotline.Application.OrderApp.OrderVisitApp;
@@ -29,6 +25,7 @@ using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Settings.TimeLimitDomain;
 using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Article;
 using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
 using Hotline.Share.Dtos.File;
 using Hotline.Share.Dtos.FlowEngine;
@@ -37,7 +34,7 @@ using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Order.Publish;
 using Hotline.Share.Dtos.Push;
 using Hotline.Share.Dtos.Settings;
-using Hotline.Share.Dtos.Users;
+using Hotline.Share.Enums.Article;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Push;
@@ -46,6 +43,7 @@ using Hotline.Share.Enums.Settings;
 using Hotline.Share.Mq;
 using Hotline.Share.Requests;
 using Hotline.Share.Tools;
+using Hotline.Snapshot;
 using Hotline.Snapshot.IRepository;
 using Hotline.Statistics;
 using Hotline.Tools;
@@ -56,15 +54,14 @@ using MapsterMapper;
 using MediatR;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Options;
-using NPOI.SS.Formula.Functions;
 using PanGu;
 using SqlSugar;
 using System.Data;
 using System.Dynamic;
-using System.Threading;
 using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
+using XF.Domain.Locks;
 using XF.Domain.Repository;
 using WordInfo = PanGu.WordInfo;
 
@@ -72,6 +69,7 @@ namespace Hotline.Application.OrderApp;
 
 public class OrderApplication : IOrderApplication, IScopeDependency
 {
+    #region 注入
     private readonly IOrderSnapshotRepository _orderSnapshotRepository;
     private readonly IMediator _mediator;
     private readonly IRepository<TranspondCityRawData> _transpondCityRawDataRepository;
@@ -83,8 +81,6 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IWorkflowDomainService _workflowDomainService;
     private readonly ISessionContext _sessionContext;
     private readonly IOrderRepository _orderRepository;
-
-    //private readonly ITimeLimitDomainService _timeLimitDomainService;
     private readonly IMapper _mapper;
     private readonly ISystemSettingCacheManager _systemSettingCacheManager;
     private readonly IRepository<OrderWord> _orderWrodRepository;
@@ -127,6 +123,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<OrderVisitDetailCopy> _orderVisitDetailCopyRepository;
     private readonly IRepository<OrderDelayAutomatic> _orderDelayAutomaticRepository;
     private readonly IRepository<Hotline.Orders.ObservationPiece> _observationPieceRepository;
+    private readonly IDistributedLock _distributedLock;
 
     public OrderApplication(
         IOrderDomainService orderDomainService,
@@ -182,9 +179,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<Role> roleRepository,
         IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository,
         IRepository<OrderDelayAutomatic> orderDelayAutomaticRepository,
-        IRepository<Hotline.Orders.ObservationPiece> observationPieceRepository
-,
-        IOrderSnapshotRepository orderSnapshotRepository)
+        IRepository<Hotline.Orders.ObservationPiece> observationPieceRepository,
+        IOrderSnapshotRepository orderSnapshotRepository,
+        IDistributedLock distributedLock)
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -240,7 +237,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _orderDelayAutomaticRepository = orderDelayAutomaticRepository;
         _observationPieceRepository = observationPieceRepository;
         _orderSnapshotRepository = orderSnapshotRepository;
+        _distributedLock = distributedLock;
     }
+    #endregion
 
     /// <summary>
     /// 更新工单办理期满时间(延期调用,其他不调用)
@@ -805,6 +804,13 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     public ISugarQueryable<Order> GetPublishOrderList(QueryOrderPublishDto dto)
     {
         var query = _orderRepository.Queryable().Includes(d => d.OrderTags);
+        if (_systemSettingCacheManager.Snapshot)
+        {
+            query = query.LeftJoin<OrderSnapshot>((d, snapshot) => d.Id == snapshot.Id)
+                .WhereIF(dto.IndustryId.NotNullOrEmpty(), (d, snapshot) => snapshot.IndustryId == dto.IndustryId)
+                .WhereIF(dto.IsRectifyDepartment.HasValue, (d, snapshot) => snapshot.IsRectifyDepartment == dto.IsRectifyDepartment)
+                .WhereIF(dto.IsDangerDepartment.HasValue, (d, snapshot) => snapshot.IsDangerDepartment == dto.IsDangerDepartment);
+        }
         if (_appOptions.Value.IsLuZhou)
             query = query.Includes(d => d.FwCallRecord);
         //.Includes(d => d.OrderPublish)
@@ -1509,7 +1515,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         //任务 314 关于修改回访结果后回访人更新的问题
         if (_appOptions.Value.IsZiGong == true)
         {
-            if (string.IsNullOrEmpty(visit.EmployeeId))
+            //if (string.IsNullOrEmpty(visit.EmployeeId)||)
+            //    visit.EmployeeId = _sessionContext.UserId;
+            if (dto.IsUpdate == false)
                 visit.EmployeeId = _sessionContext.UserId;
         }
         else
@@ -1570,8 +1578,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         }
 
         await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
-        await _orderVisitedDetailRepository.UpdateRangeAsync(visit.OrderVisitDetails, cancellationToken);
         await _orderRepository.UpdateAsync(visit.Order, cancellationToken);
+        await _orderVisitedDetailRepository.UpdateRangeAsync(visit.OrderVisitDetails, cancellationToken);
 
         //handle visit trace
         //上面取得当前操作人,需求变动前暂时可以这样写
@@ -1780,7 +1788,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 await _orderSnapshotRepository.Queryable().Where(m => m.Id == item.OrderId)
                     .Select(m => m.IndustryName)
                     .FirstAsync()
-                    .Then(name => 
+                    .Then(name =>
                     {
                         if (name.Trim() == "电气焊作业申报") code = "1012";
                     });
@@ -2121,7 +2129,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
 
         query = query
             .Includes(x => x.OrderSupervises.OrderByDescending(d => d.CreationTime).Take(2).ToList())
-            .Includes(x => x.OrderVisits.Where(q=>q.VisitState == EVisitState.Visited).Take(1).ToList(), d => d.OrderVisitDetails.Where(c => c.VisitTarget == EVisitTarget.Org).Take(1).ToList());
+            .Includes(x => x.OrderVisits.Where(q => q.VisitState == EVisitState.Visited).Take(1).ToList(), d => d.OrderVisitDetails.Where(c => c.VisitTarget == EVisitTarget.Org).Take(1).ToList());
 
         return query;
     }
@@ -5549,6 +5557,10 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             if (files != null && files.Any())
                 order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
             await _orderDomainService.AddAsync(order, cancellationToken: cancellationToken);
+
+            //不同来源渠道的待受理工单需给坐席进行待受理提醒
+            if (_appOptions.Value.IsZiGong)
+                await PendingAcceptanceReminder(order.Id, cancellationToken);
         }
         else
         {
@@ -5618,143 +5630,223 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                     _mapper.Map(dto.OrderExtension, orderExtension);
                 await _orderDomainService.UpdateExtensionAsync(orderExtension, cancellationToken);
             }
+
+            //不同来源渠道的待受理工单需给坐席进行待受理提醒
+            if (_appOptions.Value.IsZiGong)
+                await PendingAcceptanceReminder(order.Id, cancellationToken);
         }
         else
         {
-            _mapper.Map(dto, order);
-            if (files != null && files.Any())
-                order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
-            else
-                order.FileJson = new List<Share.Dtos.File.FileJson>();
-            //order.ReTransactNum++;
-            if (order.ProvinceReTransactNum.HasValue)
-                order.ProvinceReTransactNum = order.ProvinceReTransactNum + 1;
-            else
-                order.ProvinceReTransactNum = 1;
-
-            if (order.IsSecret == true)
-            {
-                order.FocusOnEventsName = "保密";
-                order.FocusOnEvents = "99";
-            }
-            //await _orderRepository.UpdateAsync(order, cancellationToken);
-
-            if (orderExtension is not null)
-            {
-                orderExtension.Id = order.Id;
-                if (dto.OrderExtension != null)
-                    _mapper.Map(dto.OrderExtension, orderExtension);
-                await _orderDomainService.UpdateExtensionAsync(orderExtension, cancellationToken);
-            }
-
-            //计算order 期满时间
-            ExpiredTimeWithConfig expiredTimeConfig;
-            if (_appOptions.Value.IsZiGong)
-            {
-                expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter,
-                    order.Adapt<OrderTimeClacInfo>());
-            }
-            else
-            {
-                //期满时间
-                //expiredTimeConfig = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToOrg, order.AcceptTypeCode);
-                expiredTimeConfig =
-                    await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
-            }
+            //分布式锁执行锁定
+            var distributedLockKey = $"provinceordervisit_{order.Id}";
+            if (await _distributedLock.AcquireAsync(distributedLockKey, TimeSpan.FromMinutes(3), cancellationToken))
+            {
+                //锁定成功,执行正常业务
+                _mapper.Map(dto, order);
+                if (files != null && files.Any())
+                    order.FileJson = await _fileRepository.AddFileAsync(files, order.Id, "", cancellationToken);
+                else
+                    order.FileJson = new List<Share.Dtos.File.FileJson>();
+                //order.ReTransactNum++;
+                if (order.ProvinceReTransactNum.HasValue)
+                    order.ProvinceReTransactNum = order.ProvinceReTransactNum + 1;
+                else
+                    order.ProvinceReTransactNum = 1;
 
-            _mapper.Map(expiredTimeConfig, order);
-            //await _orderRepository.UpdateAsync(order, cancellationToken);
-
-            //特提(撤回至发起)
-            if (!string.IsNullOrEmpty(order.WorkflowId))
-            {
-                // FlowStepHandler? handler = null;
-                // if (_appOptions.Value.IsZiGong)
-                // {
-                //     // 平均派单
-                //     var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
-                //     if (averageSendOrder)
-                //     {
-                //         handler = await _orderDomainService.AverageOrder(cancellationToken);
-                //     }
-                // }
-                //
-                // StepAssignInfo? stepAssignInfo = null;
-                // if (handler is not null)
-                // {
-                //     stepAssignInfo = _mapper.Map<StepAssignInfo>(handler);
-                //     stepAssignInfo.FlowAssignType = EFlowAssignType.User;
-                // }
-                //
-                // var reverseFlowStepAssignInfo = stepAssignInfo is null
-                //     ? new ReverseFlowStepAssignInfo(EReverseFlowStepCreationPolicy.OriginStep)
-                //     : new ReverseFlowStepAssignInfo(EReverseFlowStepCreationPolicy.OriginStepUser, stepAssignInfo);
-                //await _workflowDomainService.RecallToStartStepAsync(order.WorkflowId, "省工单重派", current, order.Status >= EOrderStatus.Filed, cancellationToken);
-
-                var flowAssignType = _appOptions.Value.IsYiBin
-                    ? EFlowAssignType.User
-                    : EFlowAssignType.Role;
-
-                var (isPaiDan, workflow) = await _workflowDomainService.RecallToCenterFirstToSendAsync(order.WorkflowId, "省工单重派",
-                    order.Status >= EOrderStatus.Filed, order.ExpiredTime, EHandleMode.Redo, flowAssignType, cancellationToken);
-
-                order.FileEmpty();
-
-                order.CurrentStepName = workflow.CurrentStepName;
-                order.CurrentStepCode = workflow.CurrentStepCode;
-                order.CurrentStepId = workflow.CurrentStepId;
-                order.CurrentStepCreateTime = workflow.CurrentStepCreateTime;
-                order.CurrentHandleTime = workflow.CurrentHandleTime;
-                order.CurrentHandlerId = workflow.CurrentHandlerId;
-                order.CurrentHandlerName = workflow.CurrentHandlerName;
-                order.CurrentHandleOrgName = workflow.CurrentHandleOrgName;
-                order.CurrentHandleOrgId = workflow.CurrentHandleOrgId;
-                order.CurrentHandleOrgLevel = workflow.CurrentHandleOrgLevel;
-                order.CurrentHandleOrgAreaCode = workflow.CurrentHandleOrgAreaCode;
-                order.CurrentHandleOrgAreaName = workflow.CurrentHandleOrgAreaName;
-
-                order.Status = EOrderStatus.WaitForAccept;
-                if (isPaiDan)
+                if (order.IsSecret == true)
                 {
-                    order.Status = EOrderStatus.Special;
+                    order.FocusOnEventsName = "保密";
+                    order.FocusOnEvents = "99";
                 }
-                //await _orderRepository.Updateable().SetColumns(o => new Order { Status = status }).Where(o => o.Id == order.Id).ExecuteCommandAsync(cancellationToken);
+                //await _orderRepository.UpdateAsync(order, cancellationToken);
 
-                //处理回访和发布信息
+                if (orderExtension is not null)
+                {
+                    orderExtension.Id = order.Id;
+                    if (dto.OrderExtension != null)
+                        _mapper.Map(dto.OrderExtension, orderExtension);
+                    await _orderDomainService.UpdateExtensionAsync(orderExtension, cancellationToken);
+                }
 
-                var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == order.Id);
-                if (publish != null)
+                //计算order 期满时间
+                ExpiredTimeWithConfig expiredTimeConfig;
+                if (_appOptions.Value.IsZiGong)
                 {
-                    var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
-                    publishHistory.OrderPublishId = publish.Id;
-                    publishHistory.ArrangeTitleAfter = publish.ArrangeTitle;
-                    publishHistory.ArrangeTitleBefor = publish.ArrangeTitle;
-                    publishHistory.ArrangeContentAfter = publish.ArrangeContent;
-                    publishHistory.ArrangeContentBefor = publish.ArrangeContent;
-                    publishHistory.ArrangeOpinionAfter = publish.ArrangeOpinion;
-                    publishHistory.ArrangeOpinionBefor = publish.ArrangeOpinion;
-                    await _orderPublishHistoryRepository.AddAsync(publishHistory, cancellationToken);
-                    await _orderPublishRepository.RemoveAsync(publish, false, cancellationToken);
+                    expiredTimeConfig = await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter,
+                        order.Adapt<OrderTimeClacInfo>());
                 }
+                else
+                {
+                    //期满时间
+                    //expiredTimeConfig = _timeLimitDomainService.CalcExpiredTime(DateTime.Now, EFlowDirection.CenterToOrg, order.AcceptTypeCode);
+                    expiredTimeConfig =
+                        await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToOrg, order.Adapt<OrderTimeClacInfo>());
+                }
+
+                _mapper.Map(expiredTimeConfig, order);
+                //await _orderRepository.UpdateAsync(order, cancellationToken);
 
-                var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == order.Id && x.VisitState != EVisitState.None);
-                if (visit != null)
+                //特提(撤回至发起)
+                if (!string.IsNullOrEmpty(order.WorkflowId))
                 {
-                    visit.VisitState = EVisitState.None;
-                    await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+                    // FlowStepHandler? handler = null;
+                    // if (_appOptions.Value.IsZiGong)
+                    // {
+                    //     // 平均派单
+                    //     var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
+                    //     if (averageSendOrder)
+                    //     {
+                    //         handler = await _orderDomainService.AverageOrder(cancellationToken);
+                    //     }
+                    // }
+                    //
+                    // StepAssignInfo? stepAssignInfo = null;
+                    // if (handler is not null)
+                    // {
+                    //     stepAssignInfo = _mapper.Map<StepAssignInfo>(handler);
+                    //     stepAssignInfo.FlowAssignType = EFlowAssignType.User;
+                    // }
+                    //
+                    // var reverseFlowStepAssignInfo = stepAssignInfo is null
+                    //     ? new ReverseFlowStepAssignInfo(EReverseFlowStepCreationPolicy.OriginStep)
+                    //     : new ReverseFlowStepAssignInfo(EReverseFlowStepCreationPolicy.OriginStepUser, stepAssignInfo);
+                    //await _workflowDomainService.RecallToStartStepAsync(order.WorkflowId, "省工单重派", current, order.Status >= EOrderStatus.Filed, cancellationToken);
+
+                    var flowAssignType = _appOptions.Value.IsYiBin
+                        ? EFlowAssignType.User
+                        : EFlowAssignType.Role;
+
+                    var (isPaiDan, workflow) = await _workflowDomainService.RecallToCenterFirstToSendAsync(order.WorkflowId, "省工单重派",
+                        order.Status >= EOrderStatus.Filed, order.ExpiredTime, EHandleMode.Redo, flowAssignType, cancellationToken);
+
+                    order.FileEmpty();
+
+                    order.CurrentStepName = workflow.CurrentStepName;
+                    order.CurrentStepCode = workflow.CurrentStepCode;
+                    order.CurrentStepId = workflow.CurrentStepId;
+                    order.CurrentStepCreateTime = workflow.CurrentStepCreateTime;
+                    order.CurrentHandleTime = workflow.CurrentHandleTime;
+                    order.CurrentHandlerId = workflow.CurrentHandlerId;
+                    order.CurrentHandlerName = workflow.CurrentHandlerName;
+                    order.CurrentHandleOrgName = workflow.CurrentHandleOrgName;
+                    order.CurrentHandleOrgId = workflow.CurrentHandleOrgId;
+                    order.CurrentHandleOrgLevel = workflow.CurrentHandleOrgLevel;
+                    order.CurrentHandleOrgAreaCode = workflow.CurrentHandleOrgAreaCode;
+                    order.CurrentHandleOrgAreaName = workflow.CurrentHandleOrgAreaName;
+
+                    order.Status = EOrderStatus.WaitForAccept;
+                    if (isPaiDan)
+                    {
+                        order.Status = EOrderStatus.Special;
+                    }
+                    //await _orderRepository.Updateable().SetColumns(o => new Order { Status = status }).Where(o => o.Id == order.Id).ExecuteCommandAsync(cancellationToken);
+
+                    //处理回访和发布信息
+
+                    var publish = await _orderPublishRepository.GetAsync(x => x.OrderId == order.Id);
+                    if (publish != null)
+                    {
+                        var publishHistory = _mapper.Map<OrderPublishHistory>(publish);
+                        publishHistory.OrderPublishId = publish.Id;
+                        publishHistory.ArrangeTitleAfter = publish.ArrangeTitle;
+                        publishHistory.ArrangeTitleBefor = publish.ArrangeTitle;
+                        publishHistory.ArrangeContentAfter = publish.ArrangeContent;
+                        publishHistory.ArrangeContentBefor = publish.ArrangeContent;
+                        publishHistory.ArrangeOpinionAfter = publish.ArrangeOpinion;
+                        publishHistory.ArrangeOpinionBefor = publish.ArrangeOpinion;
+                        await _orderPublishHistoryRepository.AddAsync(publishHistory, cancellationToken);
+                        await _orderPublishRepository.RemoveAsync(publish, false, cancellationToken);
+                    }
+
+                    var visit = await _orderVisitRepository.GetAsync(x => x.OrderId == order.Id && x.VisitState != EVisitState.None);
+                    if (visit != null)
+                    {
+                        visit.VisitState = EVisitState.None;
+                        await _orderVisitRepository.UpdateAsync(visit, cancellationToken);
+                    }
                 }
-            }
 
-            await _orderRepository.UpdateAsync(order, cancellationToken);
-            //await _workflowDomainService.RecallToStartStepAsync(order.WorkflowId, "省工单重派", current, cancellationToken);
+                await _orderRepository.UpdateAsync(order, cancellationToken);
+                //await _workflowDomainService.RecallToStartStepAsync(order.WorkflowId, "省工单重派", current, cancellationToken);
+
+                //删除甄别、延期、二次办理等数据
+                await SpecialNewVerify(order, cancellationToken);
 
-            //删除甄别、延期、二次办理等数据
-            await SpecialNewVerify(order, cancellationToken);
+                //执行完成释放分布式锁
+                await _distributedLock.ReleaseAsync(distributedLockKey, cancellationToken);
+            }
+            else
+            {
+                //锁定失败,调用消息队列,再次执行
+                _capPublisher.PublishDelay(TimeSpan.FromMinutes(2), EventNames.HotlineOrderAddAnonymous, dto);
+            }
         }
 
         return _mapper.Map<AddOrderResponse>(order);
     }
 
+    /// <summary>
+    /// 自贡任务 不同来源渠道的待受理工单需给坐席进行待受理提醒
+    /// </summary>
+    /// <param name="orderId"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    private async Task PendingAcceptanceReminder(string orderId, CancellationToken cancellationToken)
+    {
+        var order = await _orderRepository.GetAsync(p => p.Id == orderId && p.Status == EOrderStatus.WaitForAccept, cancellationToken);
+        if (order == null)
+            return;
+
+        try
+        {
+            var pendingAcceptanceReminder = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.PendingAcceptanceReminder);
+            if (pendingAcceptanceReminder != null && pendingAcceptanceReminder.Any())
+            {
+                if (pendingAcceptanceReminder.Any(p => p.DicDataValue.Contains(order.SourceChannelCode)))
+                {
+                    //查询坐席角色
+                    var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RoleZuoXi).SettingValue;
+                    var list = await _userRepository.Queryable()
+                            .Includes(u => u.Roles)
+                             .Where(u => u.Roles.Any(x => setting.Contains(x.Name)))
+                             .ToListAsync();
+
+                    //给坐席发送提醒
+                    if (list != null && list.Any())
+                    {
+                        AddCircularDto circularDto = new()
+                        {
+                            Title = "待受理提醒",
+                            Content = "您有新的【" + order.SourceChannel + "】工单待受理",
+                            CircularTypeId = "5",
+                            CircularTypeName = "系统消息",
+                            IsMustRead = true,
+                            SourceOrgId = OrgSeedData.CenterId,
+                            SourceOrgName = OrgSeedData.CenterName,
+                            CircularType = ECircularType.Person
+                        };
+                        List<CircularReadGroupDto> users = [];
+                        foreach (var user in list)
+                        {
+                            users.Add(new CircularReadGroupDto()
+                            {
+                                UserId = user.Id,
+                                UserName = user.Name,
+                            });
+                        }
+                        circularDto.CircularReadGroups = users;
+                        //调用推送消息通用接口
+                        await _circularRecordDomainService.AddCircularMessage(circularDto, cancellationToken);
+                    }
+                }
+            }
+        }
+        catch (Exception)
+        {
+        }
+
+    }
+
     /// <summary>
     /// 派单量统计
     /// </summary>

+ 13 - 2
src/Hotline.Application/SpecialNumber/SpecialNumberApplication.cs

@@ -7,6 +7,8 @@ using XF.Domain.Repository;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Share.Dtos.Special;
 using Hotline.Orders;
+using Hotline.Settings;
+using Hotline.Caching.Interfaces;
 
 namespace Hotline.Application.SpecialNumber
 {
@@ -17,15 +19,18 @@ namespace Hotline.Application.SpecialNumber
         private readonly IRepository<Hotline.Special.SpecialNumber> _specialNumberRepository;
         private readonly ISessionContext _sessionContext;
         private readonly IMapper _mapper;
+        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
 
         public SpecialNumberApplication(
             IRepository<Hotline.Special.SpecialNumber> specialNumberRepository,
             ISessionContext sessionContext,
-            IMapper mapper)
+            IMapper mapper,
+            ISystemSettingCacheManager systemSettingCacheManager)
         {
             _specialNumberRepository = specialNumberRepository;
             _sessionContext = sessionContext;
             _mapper = mapper;
+            _systemSettingCacheManager = systemSettingCacheManager;
         }
 
         #endregion
@@ -156,10 +161,16 @@ namespace Hotline.Application.SpecialNumber
         /// <returns></returns>
         public async Task<SpecialNumberInfoDto> GetSpecialNumberByAsync(string PhoneNumber, CancellationToken cancellationToken)
         {
+            var selectPushTypeCode = _systemSettingCacheManager.GetSetting(SettingConstants.SelectPushTypeCode).SettingValue;
             var data = await _specialNumberRepository.Queryable()
                 .FirstAsync(x => x.PhoneNumber == PhoneNumber, cancellationToken);
             if (data == null) return new();
-            return _mapper.Map<SpecialNumberInfoDto>(data);
+            var model = _mapper.Map<SpecialNumberInfoDto>(data);
+            if (selectPushTypeCode.Contains(model.PoliticalIdentityValue))
+            {
+                model.IsSelectPushType = true;
+            }
+            return model;
         }
 
         #endregion

+ 174 - 148
src/Hotline.Application/Subscribers/DatasharingSubscriber.cs

@@ -5,7 +5,6 @@ using Hotline.Application.FlowEngine;
 using Hotline.Application.OrderApp;
 using Hotline.Authentications;
 using Hotline.Caching.Interfaces;
-using Hotline.Caching.Services;
 using Hotline.CallCenter.Calls;
 using Hotline.Configurations;
 using Hotline.ContingencyManagement;
@@ -19,7 +18,6 @@ using Hotline.Settings.TimeLimitDomain;
 using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.ContingencyManagement;
 using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
-using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.OrderTranspond;
@@ -28,18 +26,15 @@ using Hotline.Share.Dtos.TrCallCenter;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Mq;
-using Hotline.Validators.FlowEngine;
 using Mapster;
 using MapsterMapper;
 using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
-using Newtonsoft.Json;
 using SqlSugar;
-using XF.Domain.Authentications;
 using XF.Domain.Dependency;
 using XF.Domain.Exceptions;
+using XF.Domain.Locks;
 using XF.Domain.Repository;
 
 namespace Hotline.Application.Subscribers
@@ -49,6 +44,7 @@ namespace Hotline.Application.Subscribers
     /// </summary>
     public class DataSharingSubscriber : ICapSubscribe, ITransientDependency
     {
+        #region 注入
         private readonly IRepository<OrderVisit> _orderVisitRepository;
         private readonly IMapper _mapper;
         private readonly IOrderRepository _orderRepository;
@@ -81,6 +77,7 @@ namespace Hotline.Application.Subscribers
         private readonly ICalcExpireTime _expireTime;
         private readonly ISessionContextManager _sessionContextManager;
         private readonly ILogger<DataSharingSubscriber> _logger;
+        private readonly IDistributedLock _distributedLock;
 
         public DataSharingSubscriber(
             IRepository<OrderVisit> orderVisitRepository,
@@ -114,7 +111,8 @@ namespace Hotline.Application.Subscribers
             ISystemDicDataCacheManager sysDicDataCacheManager,
             ICalcExpireTime expireTime,
             ISessionContextManager sessionContextManager,
-            ILogger<DataSharingSubscriber> logger)
+            ILogger<DataSharingSubscriber> logger,
+            IDistributedLock distributedLock)
         {
             _orderSendBackRepository = orderSendBackRepository;
             _workflowApplication = workflowApplication;
@@ -148,7 +146,9 @@ namespace Hotline.Application.Subscribers
             _expireTime = expireTime;
             _sessionContextManager = sessionContextManager;
             _logger = logger;
+            _distributedLock = distributedLock;
         }
+        #endregion
 
         /// <summary>
         /// 接收工单退回结果
@@ -613,165 +613,181 @@ namespace Hotline.Application.Subscribers
         [CapSubscribe(Hotline.Share.Mq.EventNames.SharingOrderEvlResult)]
         public async Task OrderVisitProvince(ProvinceOrderVisitDto dto, CancellationToken cancellationToken)
         {
-            var orderVisit = await _orderVisitRepository.Queryable()
-                .Includes(x => x.Order)
-                .Includes(x => x.OrderVisitDetails)
-                .Where(x => x.Order.ReceiveProvinceNo == dto.ProvinceNo &&
-                            x.VisitState == Share.Enums.Order.EVisitState.WaitForVisit).FirstAsync(cancellationToken);
-
-            if (orderVisit != null)
+            var order = await _orderRepository.Queryable().Where(x => x.ReceiveProvinceNo == dto.ProvinceNo).FirstAsync();
+            if (order == null)
+                return;
+            var distributedLockKey = $"provinceordervisit_{order.Id}";
+            //分布式锁,如果锁成功,则执行
+            if (await _distributedLock.AcquireAsync(distributedLockKey, TimeSpan.FromMinutes(3), cancellationToken))
             {
-                //处理评价结果
-                var processingResult = dto.OrgProcessingResults;
-                Kv orgProcessingResults = null;
-                if (!string.IsNullOrEmpty(processingResult))
+                //处理原始的回访逻辑
+                var orderVisit = await _orderVisitRepository.Queryable()
+                    .Includes(x => x.Order)
+                    .Includes(x => x.OrderVisitDetails)
+                    .Where(x => x.Order.ReceiveProvinceNo == dto.ProvinceNo &&
+                                x.VisitState == Share.Enums.Order.EVisitState.WaitForVisit).FirstAsync(cancellationToken);
+
+                if (orderVisit != null)
                 {
-                    var dicData = await _systemDicDataRepository.GetAsync(x => x.DicTypeCode == SysDicTypeConsts.VisitSatisfaction &&
-                                                                               x.DicDataValue == processingResult, cancellationToken);
-                    if (dicData != null)
-                    {
-                        orgProcessingResults = new Kv();
-                        orgProcessingResults.Key = dicData.DicDataValue;
-                        orgProcessingResults.Value = dicData.DicDataName;
-                    }
-
-                    if (orgProcessingResults != null)
+                    //处理评价结果
+                    var processingResult = dto.OrgProcessingResults;
+                    Kv orgProcessingResults = null;
+                    if (!string.IsNullOrEmpty(processingResult))
                     {
-                        //主表
-                        orderVisit.VisitState = Share.Enums.Order.EVisitState.Visited;
-                        orderVisit.VisitTime = dto.VisitTime;
-                        orderVisit.VisitType = dto.VisitType;
-                        orderVisit.IsCanHandle = orgProcessingResults.Key == "2";
-                        orderVisit.IsCanAiVisit = false;
-                        orderVisit.NowEvaluate = orgProcessingResults;
-                        if (_appOptions.Value.IsZiGong)
+                        var dicData = await _systemDicDataRepository.GetAsync(x => x.DicTypeCode == SysDicTypeConsts.VisitSatisfaction &&
+                                                                                   x.DicDataValue == processingResult, cancellationToken);
+                        if (dicData != null)
                         {
-                            orderVisit.EmployeeId = _systemSettingCacheManager.DefaultVisitEmployeeId;
+                            orgProcessingResults = new Kv();
+                            orgProcessingResults.Key = dicData.DicDataValue;
+                            orgProcessingResults.Value = dicData.DicDataName;
                         }
 
-                        await _orderVisitRepository.UpdateAsync(orderVisit, cancellationToken);
-                        //子表
-                        for (int i = 0; i < orderVisit.OrderVisitDetails.Count; i++)
+                        if (orgProcessingResults != null)
                         {
-                            if (orderVisit.OrderVisitDetails[i].VisitTarget == EVisitTarget.Seat)
+                            //主表
+                            orderVisit.VisitState = Share.Enums.Order.EVisitState.Visited;
+                            orderVisit.VisitTime = dto.VisitTime;
+                            orderVisit.VisitType = dto.VisitType;
+                            orderVisit.IsCanHandle = orgProcessingResults.Key == "2";
+                            orderVisit.IsCanAiVisit = false;
+                            orderVisit.NowEvaluate = orgProcessingResults;
+                            if (_appOptions.Value.IsZiGong)
                             {
-                                orderVisit.OrderVisitDetails[i].VoiceEvaluate = (EVoiceEvaluate)int.Parse(orgProcessingResults.Key);
-                                orderVisit.OrderVisitDetails[i].SeatEvaluate = (ESeatEvaluate)int.Parse(orgProcessingResults.Key);
+                                orderVisit.EmployeeId = _systemSettingCacheManager.DefaultVisitEmployeeId;
                             }
-                            else
+
+                            await _orderVisitRepository.UpdateAsync(orderVisit, cancellationToken);
+                            //子表
+                            for (int i = 0; i < orderVisit.OrderVisitDetails.Count; i++)
                             {
-                                orderVisit.OrderVisitDetails[i].OrgProcessingResults = orgProcessingResults;
+                                if (orderVisit.OrderVisitDetails[i].VisitTarget == EVisitTarget.Seat)
+                                {
+                                    orderVisit.OrderVisitDetails[i].VoiceEvaluate = (EVoiceEvaluate)int.Parse(orgProcessingResults.Key);
+                                    orderVisit.OrderVisitDetails[i].SeatEvaluate = (ESeatEvaluate)int.Parse(orgProcessingResults.Key);
+                                }
+                                else
+                                {
+                                    orderVisit.OrderVisitDetails[i].OrgProcessingResults = orgProcessingResults;
+                                }
+
+                                orderVisit.OrderVisitDetails[i].VisitContent = dto.VisitContent;
+                                orderVisit.OrderVisitDetails[i].ScreenByEndTime = await _orderDomainService.GetScreenByEndTime();
                             }
 
-                            orderVisit.OrderVisitDetails[i].VisitContent = dto.VisitContent;
-							orderVisit.OrderVisitDetails[i].ScreenByEndTime = await _orderDomainService.GetScreenByEndTime();
-						}
-
-                        await _orderVisitedDetailRepository.UpdateRangeAsync(orderVisit.OrderVisitDetails, cancellationToken);
-                        //工单
-                        orderVisit.Order.Visited(orgProcessingResults.Key, orgProcessingResults.Value);
-                        await _orderRepository.UpdateAsync(orderVisit.Order);
-
-                        ////处理网站通知差评数据
-                        //if (orderVisit.Order.Source == ESource.Hotline && orderVisit.OrderVisitDetails.Any(x => x.OrgHandledAttitude?.Key == "1" || x.OrgHandledAttitude?.Key == "2" || x.OrgProcessingResults?.Key == "1" || x.OrgProcessingResults?.Key == "2"))
-                        //{
-                        //    //包含不满意数据,重新生成新的回访
-                        //    var newOrderVisit = _mapper.Map<OrderVisit>(orderVisit);
-                        //    newOrderVisit.InitId();
-                        //    newOrderVisit.VisitState = EVisitState.NoSatisfiedWaitForVisit;
-                        //    newOrderVisit.VisitTime = null;
-                        //    newOrderVisit.IsCanHandle = false;
-                        //    newOrderVisit.IsCanAiVisit = false;
-                        //    newOrderVisit.AiVisitCount = 0;
-                        //    await _orderVisitRepository.AddAsync(newOrderVisit, cancellationToken);
-                        //    var list = _mapper.Map<List<OrderVisitDetail>>(orderVisit.OrderVisitDetails);
-                        //    list.ForEach(x =>
-                        //    {
-                        //        x.VisitId = newOrderVisit.Id;
-                        //        x.VoiceEvaluate = null;
-                        //        x.VoiceEvaluate = null;
-                        //        x.OrgHandledAttitude = null;
-                        //        x.OrgNoSatisfiedReason = null;
-                        //        x.OrgProcessingResults = null;
-                        //        x.VisitContent = "";
-                        //    });
-                        //    await _orderVisitedDetailRepository.AddRangeAsync(list, cancellationToken);
-                        //}
+                            await _orderVisitedDetailRepository.UpdateRangeAsync(orderVisit.OrderVisitDetails, cancellationToken);
+                            //工单
+                            orderVisit.Order.Visited(orgProcessingResults.Key, orgProcessingResults.Value);
+                            await _orderRepository.UpdateAsync(orderVisit.Order);
+
+                            ////处理网站通知差评数据
+                            //if (orderVisit.Order.Source == ESource.Hotline && orderVisit.OrderVisitDetails.Any(x => x.OrgHandledAttitude?.Key == "1" || x.OrgHandledAttitude?.Key == "2" || x.OrgProcessingResults?.Key == "1" || x.OrgProcessingResults?.Key == "2"))
+                            //{
+                            //    //包含不满意数据,重新生成新的回访
+                            //    var newOrderVisit = _mapper.Map<OrderVisit>(orderVisit);
+                            //    newOrderVisit.InitId();
+                            //    newOrderVisit.VisitState = EVisitState.NoSatisfiedWaitForVisit;
+                            //    newOrderVisit.VisitTime = null;
+                            //    newOrderVisit.IsCanHandle = false;
+                            //    newOrderVisit.IsCanAiVisit = false;
+                            //    newOrderVisit.AiVisitCount = 0;
+                            //    await _orderVisitRepository.AddAsync(newOrderVisit, cancellationToken);
+                            //    var list = _mapper.Map<List<OrderVisitDetail>>(orderVisit.OrderVisitDetails);
+                            //    list.ForEach(x =>
+                            //    {
+                            //        x.VisitId = newOrderVisit.Id;
+                            //        x.VoiceEvaluate = null;
+                            //        x.VoiceEvaluate = null;
+                            //        x.OrgHandledAttitude = null;
+                            //        x.OrgNoSatisfiedReason = null;
+                            //        x.OrgProcessingResults = null;
+                            //        x.VisitContent = "";
+                            //    });
+                            //    await _orderVisitedDetailRepository.AddRangeAsync(list, cancellationToken);
+                            //}
+                        }
                     }
                 }
-            }
-            else
-            {
-                //处理省下行回访
-                var order = await _orderRepository.Queryable().Where(x => x.ReceiveProvinceNo == dto.ProvinceNo).FirstAsync();
-                if (order != null && order.Status <= EOrderStatus.Filed)
+                else
                 {
-                    //判断是否有发布数据
-                    var orderPublish = await _orderPublishRepository.Queryable()
-                        .Includes(x => x.Order).Where(x => x.Order.ReceiveProvinceNo == dto.ProvinceNo).FirstAsync(cancellationToken);
-                    if (orderPublish == null)
+                    //处理省下行回访
+                    //  var order = await _orderRepository.Queryable().Where(x => x.ReceiveProvinceNo == dto.ProvinceNo).FirstAsync();
+                    if (order != null && order.Status <= EOrderStatus.Filed)
                     {
-                        orderPublish = new OrderPublish();
-                        orderPublish.OrderId = order.Id;
-                        orderPublish.No = order.No;
-                        orderPublish.PublishState = false;
-                        orderPublish.ArrangeTitle = order.Title;
-                        orderPublish.ArrangeContent = order.Content;
-                        orderPublish.ArrangeOpinion = order.FileOpinion;
-                        orderPublish.ProPublishState = false;
-                        orderPublish.FeedBackPhone = order.Contact;
-                        orderPublish.CreatorName = order.CenterToOrgHandlerId;
-                        await _orderPublishRepository.AddAsync(orderPublish);
-                        order.Publish(orderPublish.PublishState);
-                    }
+                        //判断是否有发布数据
+                        var orderPublish = await _orderPublishRepository.Queryable()
+                            .Includes(x => x.Order).Where(x => x.Order.ReceiveProvinceNo == dto.ProvinceNo).FirstAsync(cancellationToken);
+                        if (orderPublish == null)
+                        {
+                            orderPublish = new OrderPublish();
+                            orderPublish.OrderId = order.Id;
+                            orderPublish.No = order.No;
+                            orderPublish.PublishState = false;
+                            orderPublish.ArrangeTitle = order.Title;
+                            orderPublish.ArrangeContent = order.Content;
+                            orderPublish.ArrangeOpinion = order.FileOpinion;
+                            orderPublish.ProPublishState = false;
+                            orderPublish.FeedBackPhone = order.Contact;
+                            orderPublish.CreatorName = order.CenterToOrgHandlerId;
+                            await _orderPublishRepository.AddAsync(orderPublish);
+                            order.Publish(orderPublish.PublishState);
+                        }
 
-                    orderVisit = new OrderVisit();
-                    orderVisit.No = order.No;
-                    orderVisit.OrderId = order.Id;
-                    orderVisit.PublishTime = DateTime.Now;
-                    orderVisit.IsCanHandle = true;
-                    orderVisit.EmployeeId = order.CenterToOrgHandlerId;
-                    orderVisit.VisitState = EVisitState.None;
-                    orderVisit.VisitTime = dto.VisitTime;
-                    orderVisit.VisitType = dto.VisitType;
-                    orderVisit.IsCanAiVisit = false;
-                    var VisitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction)
-                        .Where(x => x.DicDataValue == dto.OrgProcessingResults).Select(m => new Kv { Key = m.DicDataValue, Value = m.DicDataName })
-                        .FirstOrDefault();
-                    var satisfy = VisitSatisfaction;
-                    orderVisit.NowEvaluate = satisfy;
-                    string visitId = await _orderVisitRepository.AddAsync(orderVisit);
-
-                    //新增回访信息
-                    var visitedDetail = new List<OrderVisitDetail>();
-
-                    //新增坐席回访
-                    var seatDetail = new OrderVisitDetail();
-                    seatDetail.VisitId = visitId;
-                    seatDetail.VisitTarget = EVisitTarget.Seat;
-                    seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
-                    seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
-                    visitedDetail.Add(seatDetail);
-
-                    //新增部门回访
-                    var orgDetail = new OrderVisitDetail();
-                    orgDetail.VisitId = visitId;
-                    orgDetail.VisitOrgCode = order.ActualHandleOrgCode;
-                    orgDetail.VisitOrgName = order.ActualHandleOrgName;
-                    orgDetail.VisitTarget = EVisitTarget.Org;
-					orgDetail.ScreenByEndTime = await _orderDomainService.GetScreenByEndTime();
-
-					orgDetail.OrgProcessingResults = satisfy;
-
-                    visitedDetail.Add(orgDetail);
-                    //TODO 自贡办件态度
-
-
-                    await _orderVisitedDetailRepository.AddRangeAsync(visitedDetail, cancellationToken);
-                    //order.Visited(satisfy.Key, satisfy.Value);
-                    //order.Status = EOrderStatus.Visited;
-                    //await _orderRepository.UpdateAsync(order, cancellationToken);
+                        orderVisit = new OrderVisit();
+                        orderVisit.No = order.No;
+                        orderVisit.OrderId = order.Id;
+                        orderVisit.PublishTime = DateTime.Now;
+                        orderVisit.IsCanHandle = true;
+                        orderVisit.EmployeeId = order.CenterToOrgHandlerId;
+                        orderVisit.VisitState = EVisitState.None;
+                        orderVisit.VisitTime = dto.VisitTime;
+                        orderVisit.VisitType = dto.VisitType;
+                        orderVisit.IsCanAiVisit = false;
+                        var VisitSatisfaction = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.VisitSatisfaction)
+                            .Where(x => x.DicDataValue == dto.OrgProcessingResults).Select(m => new Kv { Key = m.DicDataValue, Value = m.DicDataName })
+                            .FirstOrDefault();
+                        var satisfy = VisitSatisfaction;
+                        orderVisit.NowEvaluate = satisfy;
+                        string visitId = await _orderVisitRepository.AddAsync(orderVisit);
+
+                        //新增回访信息
+                        var visitedDetail = new List<OrderVisitDetail>();
+
+                        //新增坐席回访
+                        var seatDetail = new OrderVisitDetail();
+                        seatDetail.VisitId = visitId;
+                        seatDetail.VisitTarget = EVisitTarget.Seat;
+                        seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
+                        seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
+                        visitedDetail.Add(seatDetail);
+
+                        //新增部门回访
+                        var orgDetail = new OrderVisitDetail();
+                        orgDetail.VisitId = visitId;
+                        orgDetail.VisitOrgCode = order.ActualHandleOrgCode;
+                        orgDetail.VisitOrgName = order.ActualHandleOrgName;
+                        orgDetail.VisitTarget = EVisitTarget.Org;
+                        orgDetail.ScreenByEndTime = await _orderDomainService.GetScreenByEndTime();
+
+                        orgDetail.OrgProcessingResults = satisfy;
+
+                        visitedDetail.Add(orgDetail);
+                        //TODO 自贡办件态度
+
+
+                        await _orderVisitedDetailRepository.AddRangeAsync(visitedDetail, cancellationToken);
+                        //order.Visited(satisfy.Key, satisfy.Value);
+                        //order.Status = EOrderStatus.Visited;
+                        //await _orderRepository.UpdateAsync(order, cancellationToken);
+                    }
                 }
+
+                //执行完成释放分布式锁
+                await _distributedLock.ReleaseAsync(distributedLockKey, cancellationToken);
+            }
+            else
+            {
+                throw new UserFriendlyException($"分布式锁定失败, orderId: {order.Id}");
             }
         }
 
@@ -1313,5 +1329,15 @@ namespace Hotline.Application.Subscribers
                 }
             }
         }
+
+        /// <summary>
+        /// 分布式执行省工单重派业务
+        /// </summary>
+        /// <returns></returns>
+        [CapSubscribe(EventNames.HotlineOrderAddAnonymous)]
+        public async Task HotlineOrderAddAnonymous(AddOrderDto dto, CancellationToken cancellationToken)
+        {
+            await _orderApplication.ReceiveOrderFromExternalAsync(dto, cancellationToken);
+        }
     }
 }

+ 1 - 1
src/Hotline.Share/Dtos/Article/BulletinDto.cs

@@ -243,7 +243,7 @@ namespace Hotline.Share.Dtos.Article
         /// </summary>
         public DateTime? ExaminTime { get; set; }
 
-        public List<FileDto> Files { get; set; }
+        public List<FileDto>? Files { get; set; }
 
         /// <summary>
         /// 附件

+ 2 - 0
src/Hotline.Share/Dtos/CallCenter/BiSeatCallsDto.cs

@@ -141,6 +141,8 @@ public class BiSeatCallsDto
 
 public class BiSeatRestDto
 {
+    public string DayTime { get; set; }
+
     public string UserId { get; set; }
     public string? StaffNo { get; set; }
 

+ 3 - 0
src/Hotline.Share/Dtos/DataSharing/PusherHotlineDto/ProvinceOrderVisitDto.cs

@@ -8,14 +8,17 @@ public class ProvinceOrderVisitDto
     /// 工单编号
     /// </summary>
     public string ProvinceNo { get; set; }
+
     /// <summary>
     /// 回访时间
     /// </summary>
     public DateTime? VisitTime { get; set; }
+
     /// <summary>
     /// 回访方式
     /// </summary>
     public EVisitType? VisitType { get; set; }
+
     /// <summary>
     /// 回访内容
     /// </summary>

+ 15 - 0
src/Hotline.Share/Dtos/Order/Publish/QueryOrderPublishDto.cs

@@ -162,4 +162,19 @@ public record QueryOrderPublishDto : PagedKeywordRequest
     /// 省来源分类 1:政民互动直派 2:政民互动  3:省12345
     /// </summary>
     public string? ProvinceChannel { get; set; }
+
+    /// <summary>
+    /// 随手拍行业Id
+    /// </summary>
+    public string? IndustryId { get; set; }
+
+    /// <summary>
+    /// 是否整改;
+    /// </summary>
+    public bool? IsRectifyDepartment { get; set; }
+
+    /// <summary>
+    /// 是否存在安全隐患
+    /// </summary>
+    public bool? IsDangerDepartment { get; set; }
 }

+ 5 - 0
src/Hotline.Share/Dtos/Special/SpecialNumberDto.cs

@@ -113,5 +113,10 @@ namespace Hotline.Share.Dtos.Special
         /// 创建时间
         /// </summary>
         public DateTime? CreationTime { get; set; }
+
+        /// <summary>
+        /// 是否选择推送类型
+        /// </summary>
+        public bool IsSelectPushType { get; set; } = false;
     }
 }

+ 6 - 1
src/Hotline.Share/Dtos/TrCallCenter/TrTelDao.cs

@@ -861,7 +861,7 @@ namespace Hotline.Share.Dtos.TrCallCenter
         /// 用户名
         /// </summary>
         public string UserName { get; set; }
-        
+
         /// <summary>
         /// 开始时间
         /// </summary>
@@ -1228,6 +1228,11 @@ namespace Hotline.Share.Dtos.TrCallCenter
         /// </summary>
         public double Duration { get; private set; }
 
+        /// <summary>
+        /// 用时分钟
+        /// </summary>
+        public double DurationMinutes => Math.Round((double)Duration / 60, 2);
+
     }
 
     public class TelActionListXthx

+ 9 - 2
src/Hotline.Share/Dtos/Users/UserDto.cs

@@ -3,6 +3,7 @@ using Hotline.Share.Dtos.Roles;
 using Hotline.Share.Enums.Identity;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.User;
+using System.Security.Principal;
 using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.Users;
@@ -29,6 +30,12 @@ public record UserDto : AddUserDto
     public IReadOnlyList<RoleDto> Roles { get; set; }
 
     public OrgDto Organization { get; set; }
+
+    public DateTime? AccountLockoutEnd { get; set; }
+
+    public bool? AccountLockoutEnabled { get; set; }
+
+    public bool? IsNormal => (AccountLockoutEnabled.HasValue && AccountLockoutEnabled == true) && (AccountLockoutEnd.HasValue && AccountLockoutEnd >= DateTime.Now) ? false : true;
 }
 
 public record AddUserDto
@@ -125,7 +132,7 @@ public record UpdateUserDto
     /// 部门Id
     /// </summary>
     public string? OrgId { get; set; }
-    
+
     /// <summary>
     /// 部门全名
     /// </summary>
@@ -140,7 +147,7 @@ public record UpdateUserDto
     /// 默认分机号
     /// </summary>
     public string? DefaultTelNo { get; set; }
-    
+
     /// <summary>
     /// 默认分机组(技能组)
     /// </summary>

+ 5 - 0
src/Hotline.Share/Mq/EventNames.Order.cs

@@ -119,6 +119,11 @@ namespace Hotline.Share.Mq
         /// 处理每天办理完成未及时推送办理结果的数据 
         /// </summary>
         public const string HotlineFiledOrdersRepublish = "hotline.filed.orders.republish";
+
+        /// <summary>
+        /// 分布式执行省工单重派业务
+        /// </summary>
+        public const string HotlineOrderAddAnonymous = "hotline.order.add.anonymous";
         #endregion
 
         #region 内部订阅

+ 20 - 18
src/Hotline/Orders/DatabaseEventHandler/OrderVisitDetailEventHandler.cs

@@ -45,34 +45,36 @@ public class OrderVisitDetailEventHandler : IUpdateDatabaseEvent<OrderVisitDetai
         var name = "回填Order回访字段";
         if (visit.VisitTarget == EVisitTarget.Org && visit.OrgProcessingResults != null)
         {
-            var orderId = _orderVisitRepository.Queryable()
-               .Where(m => m.Id == visit.VisitId)
-               .Select(m => new { m.OrderId, m.No, m.VisitState })
-               .First();
+            var orderEntity = _orderVisitRepository.Queryable()
+                .LeftJoin<Order>((vi, order) => vi.OrderId == order.Id)
+                .Where((vi, order) => vi.Id == visit.VisitId)
+                .Select((vi, order) => new { vi.OrderId, vi.No, vi.VisitState , order.Status})
+                .First();
 
-            if (visit.OrgProcessingResults.Value == "不满意" && orderId.VisitState!= EVisitState.Visited) return;
-           
-            _orderRepository.Updateable()
+            if (visit.OrgProcessingResults.Value == "不满意" && orderEntity.VisitState != EVisitState.Visited) return;
+
+            var count = _orderRepository.Updateable()
                 .SetColumns(m => m.OrgProcessingResults == visit.OrgProcessingResults)
-                .Where(m => m.Id == orderId.OrderId && m.Status >= EOrderStatus.Published)
+                .Where(m => m.Id == orderEntity.OrderId && m.Status >= EOrderStatus.Published)
                 .ExecuteCommand();
-            _systemLogRepository.Add(name, $"OrgProcessingResults: {visit.OrgProcessingResults.ToJson()}", orderId.No, orderId.No, 1);
+            _systemLogRepository.Add(name, $"OrgProcessingResults: {visit.OrgProcessingResults.ToJson()}", orderEntity.No, orderEntity.No, 1, $"受影响行数:{count} 工单状态: {orderEntity.Status}");
         }
 
         if (visit.VisitTarget == EVisitTarget.Seat && visit.SeatEvaluate != null)
         {
-            var orderId = _orderVisitRepository.Queryable()
-               .Where(m => m.Id == visit.VisitId)
-               .Select(m => new { m.OrderId, m.No,m.VisitState })
-               .First();
+            var orderEntity = _orderVisitRepository.Queryable()
+                .LeftJoin<Order>((vi, order) => vi.OrderId == order.Id)
+                .Where((vi, order) => vi.Id == visit.VisitId)
+                .Select((vi, order) => new { vi.OrderId, vi.No, vi.VisitState, order.Status })
+                .First();
+
+            if ((visit.SeatEvaluate == ESeatEvaluate.NoSatisfied || visit.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied) && orderEntity.VisitState != EVisitState.Visited) return;
 
-            if ((visit.SeatEvaluate == ESeatEvaluate.NoSatisfied || visit.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied) && orderId.VisitState!= EVisitState.Visited) return;
-           
-            _orderRepository.Updateable()
+            var count = _orderRepository.Updateable()
                 .SetColumns(m => m.SeatEvaluate == visit.SeatEvaluate)
-                .Where(m => m.Id == orderId.OrderId && m.Status >= EOrderStatus.Published)
+                .Where(m => m.Id == orderEntity.OrderId && m.Status >= EOrderStatus.Published)
                 .ExecuteCommand();
-            _systemLogRepository.Add(name, $"SeatEvaluate: {visit.SeatEvaluate}",orderId.No, orderId.No, 1);
+            _systemLogRepository.Add(name, $"SeatEvaluate: {visit.SeatEvaluate}", orderEntity.No, orderEntity.No, 1, $"受影响行数:{count} 工单状态: {orderEntity.Status}");
         }
 
     }

+ 7 - 7
src/Hotline/Orders/Order.cs

@@ -1369,15 +1369,15 @@ namespace Hotline.Orders
         /// </summary>
         public void Visited(string resultCode, string result)
         {
-            if (string.IsNullOrEmpty(resultCode) || string.IsNullOrEmpty(result))
+			if (Status >= EOrderStatus.Filed)
+				Status = EOrderStatus.Visited;
+			if (string.IsNullOrEmpty(resultCode) || string.IsNullOrEmpty(result))
                 return;
-            if (!string.IsNullOrEmpty(FirstVisitResultCode)) return;
-            FirstVisitResultCode = resultCode;
-            FirstVisitResult = result;
-
+            if (string.IsNullOrEmpty(FirstVisitResultCode)) {
+				FirstVisitResultCode = resultCode;
+				FirstVisitResult = result;
+			}
             //Progress = EProgress.Visited;
-            if (Status >= EOrderStatus.Filed)
-                Status = EOrderStatus.Visited;
         }
 
         public void CenterToOrg(string timelimit, int timelimitCount, ETimeType timilimitUnit,

+ 5 - 0
src/Hotline/Settings/SettingConstants.cs

@@ -776,6 +776,11 @@ namespace Hotline.Settings
         /// </summary>
         public const string SpecialIdentityVerification = "SpecialIdentityVerification";
 
+        /// <summary>
+        /// 选择推送类型的政治身份
+        /// </summary>
+        public const string SelectPushTypeCode = "SelectPushTypeCode";
+
         /// <summary>
         /// 甄别统计查询节点
         /// </summary>

+ 5 - 0
src/Hotline/Settings/SysDicTypeConsts.cs

@@ -346,4 +346,9 @@ public class SysDicTypeConsts
     /// 随手拍安全员类型
     /// </summary>
     public const string SafetyType = "SafetyType";
+
+    /// <summary>
+    /// 待受理工单提醒来源
+    /// </summary>
+    public const string PendingAcceptanceReminder = "PendingAcceptanceReminder";
 }

+ 17 - 0
test/Hotline.Tests/Application/OrderApplicationTest.cs

@@ -4,8 +4,10 @@ using Hotline.Early;
 using Hotline.Orders;
 using Hotline.Push.FWMessage;
 using Hotline.Push.Notifies;
+using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Settings;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.Order.Publish;
 using Hotline.Share.Dtos.Settings;
 using Hotline.Share.Enums.Order;
 using Mapster;
@@ -64,4 +66,19 @@ public class OrderApplicationTest
         var b = a.Adapt<SystemDicDataOutDto>();
         b.ShouldNotBeNull();
     }
+
+    [Fact]
+    public async Task GetPublishOrderList_Test()
+    { 
+        var inDto = new QueryOrderPublishDto
+        {
+            StartTime = DateTime.Now.AddDays(-30),
+            EndTime = DateTime.Now,
+            PageSize = 10,
+            PageIndex = 1,
+        };
+
+        var items = await _orderApplication.GetPublishOrderList(inDto).ToPagedListAsync(inDto);
+        items.Total.ShouldNotBe(0);
+    }
 }