Bläddra i källkod

Merge branch 'test' into test_20250424tj

tangjiang 1 vecka sedan
förälder
incheckning
797ade4e4d
29 ändrade filer med 676 tillägg och 321 borttagningar
  1. 3 3
      src/Hotline.Api/Controllers/CallController.cs
  2. 4 4
      src/Hotline.Api/Controllers/CallNativeContrroller.cs
  3. 1 1
      src/Hotline.Api/Controllers/EnterprisesController.cs
  4. 4 4
      src/Hotline.Api/Controllers/IPPbxController.cs
  5. 1 2
      src/Hotline.Api/Controllers/IdentityController.cs
  6. 3 3
      src/Hotline.Api/Controllers/IndustrialManagementController.cs
  7. 5 5
      src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs
  8. 1 1
      src/Hotline.Api/Controllers/KnowledgeCommonController.cs
  9. 170 24
      src/Hotline.Api/Controllers/KnowledgeController.cs
  10. 70 64
      src/Hotline.Api/Controllers/OrderController.cs
  11. 11 2
      src/Hotline.Api/Controllers/OrderRevocationController.cs
  12. 1 1
      src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs
  13. 6 1
      src/Hotline.Application/OrderApp/Handlers/OrderDelayHandler/OrderDelayBatchReviewTaskCompetedHandler.cs
  14. 4 2
      src/Hotline.Application/OrderApp/OrderApplication.cs
  15. 5 0
      src/Hotline.Share/Dtos/Knowledge/KnowledgeApproveDto.cs
  16. 5 0
      src/Hotline.Share/Dtos/Knowledge/KnowledgeDto.cs
  17. 4 0
      src/Hotline.Share/Dtos/Order/OrderVisitDto.cs
  18. 5 0
      src/Hotline.Share/Dtos/Order/PublishedDto.cs
  19. 34 0
      src/Hotline.Share/Enums/Order/EAduitState.cs
  20. 4 4
      src/Hotline/BatchTask/ApptaskDomainService.cs
  21. 2 0
      src/Hotline/Caching/Interfaces/ISystemSettingCacheManager.cs
  22. 2 0
      src/Hotline/Caching/Services/SystemSettingCacheManager.cs
  23. 25 0
      src/Hotline/KnowledgeBase/KnowledgeRecord.cs
  24. 34 29
      src/Hotline/Orders/IOrderDomainService.cs
  25. 1 1
      src/Hotline/Orders/ObservationPiece.cs
  26. 201 151
      src/Hotline/Orders/OrderDomainService.cs
  27. 67 18
      test/Hotline.Tests/Controller/OrderDelayControllerTest.cs
  28. 1 1
      test/Hotline.Tests/Mock/OrderServiceMock.cs
  29. 2 0
      test/Hotline.Tests/Startup.cs

+ 3 - 3
src/Hotline.Api/Controllers/CallController.cs

@@ -105,7 +105,7 @@ namespace Hotline.Api.Controllers
         /// 签入
         /// </summary>
         [HttpPost("signin")]
-        [LogFilter("分机签入")]
+        [LogFilterAlpha("分机签入")]
         public Task<TrOnDutyResponseDto> SignIn([FromBody] SignInDto dto)
             => _callApplication.SignInAsync(dto, HttpContext.RequestAborted);
 
@@ -113,7 +113,7 @@ namespace Hotline.Api.Controllers
         /// 签出
         /// </summary>
         [HttpPost("signout")]
-        [LogFilter("分机签出")]
+        [LogFilterAlpha("分机签出")]
         public Task SignOut()
             => _callApplication.SingOutAsync(HttpContext.RequestAborted);
 
@@ -121,7 +121,7 @@ namespace Hotline.Api.Controllers
         /// 签出
         /// </summary>
         [HttpPost("signout/{telNo}")]
-        [LogFilter("分机签出")]
+        [LogFilterAlpha("分机签出")]
         public Task SignOut(string telNo)
             => _callApplication.SingOutAsync(telNo, HttpContext.RequestAborted);
 

+ 4 - 4
src/Hotline.Api/Controllers/CallNativeContrroller.cs

@@ -92,7 +92,7 @@ namespace Hotline.Api.Controllers
         /// <param name="phone"></param>
         /// <returns></returns>
         [HttpDelete("delete-black-phone/{phone}")]
-        [LogFilter("删除黑名单")]
+        [LogFilterAlpha("删除黑名单")]
         public async Task DeleteBlackPhone(string phone)
         {
             var row = await _db.Deleteable<XingtangBlackPhone>().Where(p => p.StartPhone == phone).ExecuteCommandAsync();
@@ -114,7 +114,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost("add-black-phone")]
-        [LogFilter("新增黑名单")]
+        [LogFilterAlpha("新增黑名单")]
         public async Task AddBlackPhone([FromBody] AddBlackPhoneDto dto)
         {
             if (string.IsNullOrEmpty(dto.PhoneNum))
@@ -182,7 +182,7 @@ namespace Hotline.Api.Controllers
         /// <param name="phone"></param>
         /// <returns></returns>
         [HttpDelete("delete-white-phone/{phone}")]
-        [LogFilter("删除白名单")]
+        [LogFilterAlpha("删除白名单")]
         public async Task DeleteWhitePhone(string phone)
         {
             var row = await _db.Deleteable<XingtangWhitePhone>().Where(p => p.Phone == phone).ExecuteCommandAsync();
@@ -204,7 +204,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost("add-white-phone")]
-        [LogFilter("新增白名单")]
+        [LogFilterAlpha("新增白名单")]
         public async Task AddWhitePhone([FromBody] AddBlackPhoneDto dto)
         {
             if (string.IsNullOrEmpty(dto.PhoneNum))

+ 1 - 1
src/Hotline.Api/Controllers/EnterprisesController.cs

@@ -35,7 +35,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpGet("enterprise/list")]
-        [LogFilter("查询企业列表")]
+        [LogFilterAlpha("查询企业列表")]
         public async Task<YbEnterprisePaged> QueryYbEnterprises([FromQuery] PagedKeywordRequest dto)
         {
             return await _enterpriseService.QueryYbEnterprisesAsync(dto.Keyword!, dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

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

@@ -263,7 +263,7 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [LogFilter("新增黑白名单")]
+        [LogFilterAlpha("新增黑白名单")]
         [HttpPost("add-blacklist")]
         public async Task AddBlacklist([FromBody] TrAddBlacklistDto dto)
         {
@@ -275,7 +275,7 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [LogFilter("删除黑白名单")]
+        [LogFilterAlpha("删除黑白名单")]
         [HttpPost("remove-blacklist")]
         public async Task DelBlacklist([FromBody] TrDelBlacklistDto dto)
         {
@@ -385,7 +385,7 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpPost("rest")]
-        [LogFilter("分机小休")]
+        [LogFilterAlpha("分机小休")]
         public async Task Rest([FromBody] TrRestDto dto)
         {
             var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);
@@ -408,7 +408,7 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpPost("unrest")]
-        [LogFilter("分机取消小休")]
+        [LogFilterAlpha("分机取消小休")]
         public async Task UnRest()
         {
             var work = _userCacheManager.GetWorkByUser(_sessionContext.RequiredUserId);

+ 1 - 2
src/Hotline.Api/Controllers/IdentityController.cs

@@ -106,8 +106,7 @@ jxrWXHbT1FB6DqkdOnBbQqS1Azqz5HxLlSyEK3F60e3SgB5iZsDZ
         if (request is null)
             throw UserFriendlyException.SameMessage("用户名或密码错误!");
         string res;
-        if (bool.TryParse(_systemSettingCacheManager.GetSetting(SettingConstants.IsReplayLoginCheck)?.SettingValue[0],
-                out var isReplayCheck) && isReplayCheck)
+        if (_systemSettingCacheManager.IsReplayLoginCheck)
         {
             res = await _identityAppService.LoginWithSignatureAsync(request, HttpContext.RequestAborted);
         }

+ 3 - 3
src/Hotline.Api/Controllers/IndustrialManagementController.cs

@@ -79,7 +79,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost("industryadd")]
-        [LogFilter("新增行业")]
+        [LogFilterAlpha("新增行业")]
         public async Task Add([FromBody] IndustryAddDto dto)
         {
             if (dto == null)
@@ -115,7 +115,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost("industryupdate")]
-        [LogFilter("修改行业")]
+        [LogFilterAlpha("修改行业")]
         public async Task Update([FromBody] IndustryUpdateDto dto)
         {
             if (dto == null)
@@ -164,7 +164,7 @@ namespace Hotline.Api.Controllers
         /// <param name="id"></param>
         /// <returns></returns>
         [HttpDelete("{id}")]
-        [LogFilter("删除行业")]
+        [LogFilterAlpha("删除行业")]
         public async Task Remove(string id)
         {
             await _industrialManagementRepository.DelIndustrialManagementAsync(id, cancellationToken: HttpContext.RequestAborted);

+ 5 - 5
src/Hotline.Api/Controllers/JudicialManagementOrdersController.cs

@@ -94,7 +94,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost]
-        [LogFilter("新增司法工单")]
+        [LogFilterAlpha("新增司法工单")]
         public async Task<string> Add([FromBody] JudicialManagementAddOrderDto dto)
         {
             dto.InitAddress();
@@ -131,7 +131,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut]
-        [LogFilter("更新司法工单")]
+        [LogFilterAlpha("更新司法工单")]
         public async Task Update([FromBody] JudicialManagementUpdateOrderDto dto)
         {
             dto.InitAddress();
@@ -176,7 +176,7 @@ namespace Hotline.Api.Controllers
         /// <param name="id"></param>
         /// <returns></returns>
         [HttpGet]
-        [LogFilter("启用/禁用司法工单")]
+        [LogFilterAlpha("启用/禁用司法工单")]
         public async Task Update(string id)
         {
             var order = await _judicialManagementOrdersRepository.GetAsync(id, HttpContext.RequestAborted);
@@ -195,7 +195,7 @@ namespace Hotline.Api.Controllers
         ///// <param name="dto"></param>
         ///// <returns></returns>
         //[HttpPut("associated_law_enforcement_gencies")]
-        //[LogFilter("关联执法部门")]
+        //[LogFilterAlpha("关联执法部门")]
         //public async Task AssociatedLawEnforcementAgencies([FromBody] AssociatedLawEnforcementAgenciesDto dto)
         //{
         //    if (dto.LawEnforcementAgencies == null || dto.LawEnforcementAgencies.Count == 0)
@@ -277,7 +277,7 @@ namespace Hotline.Api.Controllers
         /// <param name="id"></param>
         /// <returns></returns>
         [HttpDelete("{id}")]
-        [LogFilter("删除工单")]
+        [LogFilterAlpha("删除工单")]
         public async Task Remove(string id)
         {
             var order = await _judicialManagementOrdersRepository.GetAsync(id, HttpContext.RequestAborted);

+ 1 - 1
src/Hotline.Api/Controllers/KnowledgeCommonController.cs

@@ -233,7 +233,7 @@ namespace Hotline.Api.Controllers
                     {
                         Id = it.Id.SelectAll(),
                         KnowledgeNum = SqlFunc.Subqueryable<Knowledge>()
-                            .Where(k => k.CreatorOrgId.StartsWith(it.Id))
+                            .Where(k => k.CreatorOrgId.StartsWith(it.Id) && k.IsDeleted == false)
                             .WhereIF(!string.IsNullOrEmpty(Attribution), k => k.Attribution == Attribution).DistinctCount(k => k.Id)
 
                     }).OrderBy(d => d.Id);

+ 170 - 24
src/Hotline.Api/Controllers/KnowledgeController.cs

@@ -39,6 +39,7 @@ using MiniExcelLibs;
 using NPOI.SS.Formula.Functions;
 using SqlSugar;
 using System.Text;
+using System.Threading;
 using XF.Domain.Authentications;
 using XF.Domain.Exceptions;
 using XF.Domain.Repository;
@@ -75,6 +76,7 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<KnowledgeQuestions> _knowledgeQuestionsRepository;
         private readonly IRepository<KnowledgeCorrection> _knowledgeCorrectionRepository;
         private readonly IRepository<KnowledgeCollect> _knowledgeCollectRepository;
+        private readonly IRepository<KnowledgeRecord> _knowledgeRecordRepository;
         private readonly ISystemDomainService _systemDomainService;
         private readonly IRepository<KnowledgeComment> _knowledgeCommentRepository;
         private readonly ISystemOrganizeRepository _systemOrganizeRepository;
@@ -104,6 +106,7 @@ namespace Hotline.Api.Controllers
             IRepository<KnowledgeQuestions> knowledgeQuestionsRepository,
             IRepository<KnowledgeCorrection> knowledgeCorrectionRepository,
             IRepository<KnowledgeCollect> knowledgeCollectRepository,
+            IRepository<KnowledgeRecord> knowledgeRecordRepository,
             ISystemDomainService systemDomainService,
             IRepository<KnowledgeComment> knowledgeCommentRepository,
             ISystemOrganizeRepository systemOrganizeRepository,
@@ -140,6 +143,7 @@ namespace Hotline.Api.Controllers
             _knowledgeQuestionsRepository = knowledgeQuestionsRepository;
             _knowledgeCorrectionRepository = knowledgeCorrectionRepository;
             _knowledgeCollectRepository = knowledgeCollectRepository;
+            _knowledgeRecordRepository = knowledgeRecordRepository;
             _systemDomainService = systemDomainService;
             _knowledgeCommentRepository = knowledgeCommentRepository;
             _systemOrganizeRepository = systemOrganizeRepository;
@@ -169,7 +173,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost("add")]
-        [LogFilter("知识新增")]
+        [LogFilterAlpha("知识新增")]
         public async Task<string> AddKnowledge([FromBody] AddStartFlowDto dto)
         {
             //var addDto = _mapper.Map<AddKnowledgeDto>(dto.Data);
@@ -239,7 +243,7 @@ namespace Hotline.Api.Controllers
         /// <param name="Id"></param>
         /// <returns></returns>
         [HttpPut("offshelf")]
-        [LogFilter("知识下架")]
+        [LogFilterAlpha("知识下架")]
         public async Task KnowledgeOffShelf([FromBody] OffShelfStartFlowDto dto)
         {
             var know = await _knowledgeRepository.GetAsync(dto.Data.Id, HttpContext.RequestAborted);
@@ -278,7 +282,7 @@ namespace Hotline.Api.Controllers
         /// 知识库-知识下架(new)
         /// </summary>
         [HttpPost("offshelf")]
-        [LogFilter("知识下架")]
+        [LogFilterAlpha("知识下架")]
         public Task OffShelf([FromBody] OffShelfKnowledgeDto dto) =>
             _knowledgeDomainService.OffShelfAsync(dto, HttpContext.RequestAborted);
 
@@ -286,7 +290,7 @@ namespace Hotline.Api.Controllers
         /// 知识库-知识下架并发起审批(new)
         /// </summary>
         [HttpPost("offshelf-and-approve")]
-        [LogFilter("知识下架并发起审批")]
+        [LogFilterAlpha("知识下架并发起审批")]
         public async Task OffShelfAndApprove([FromBody] OffShelfKnowledgeDto dto)
         {
             var kn = await _knowledgeDomainService.OffShelfAsync(dto, HttpContext.RequestAborted);
@@ -301,7 +305,7 @@ namespace Hotline.Api.Controllers
         /// <param name="Id"></param>
         /// <returns></returns>
         [HttpPut("ontheshelf")]
-        [LogFilter("知识上架")]
+        [LogFilterAlpha("知识上架")]
         public async Task KnowledgeOnTheShelf(string Id)
         {
             var know = await _knowledgeRepository.GetAsync(Id, HttpContext.RequestAborted);
@@ -325,7 +329,7 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpPost("ontheshelfbatch")]
-        [LogFilter("批量上架")]
+        [LogFilterAlpha("批量上架")]
         public async Task KnowledgeOnTheShelfBatch([FromBody] UnshelveBatchRequest request)
         {
             var kns = request.KnowledgeIds.Select(d => new Knowledge
@@ -337,7 +341,7 @@ namespace Hotline.Api.Controllers
             }).ToList();
             await _knowledgeRepository.Updateable(kns)
                 .UpdateColumns(d => d.Status)
-                .Where(d => d.Status == EKnowledgeStatus.OffShelf)
+                //.WhereColumns(d => d.Status == EKnowledgeStatus.OffShelf)
                 .ExecuteCommandAsync(HttpContext.RequestAborted);
         }
 
@@ -362,7 +366,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut("update")]
-        [LogFilter("知识修改")]
+        [LogFilterAlpha("知识修改")]
         public async Task UpdateKnowledge([FromBody] UpdateStartFlowDto dto)
         {
             var knowledge = await _knowledgeRepository.GetAsync(dto.Data.Id);
@@ -434,7 +438,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut]
-        [LogFilter("知识修改")]
+        [LogFilterAlpha("知识修改")]
         public Task Update([FromBody] UpdateKnowledgeDto dto) =>
             _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
 
@@ -444,7 +448,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut("update-and-approve")]
-        [LogFilter("知识修改")]
+        [LogFilterAlpha("知识修改")]
         public async Task UpdateAndApprove([FromBody] UpdateKnowledgeAndApproveDto dto)
         {
             var kn = await _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
@@ -473,7 +477,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut("update-and-approve-batch")]
-        [LogFilter("知识修改批量")]
+        [LogFilterAlpha("知识修改批量")]
         public async Task UpdateAndApproveBatch([FromBody] UpdateKnowledgeAndApproveBatchDto dto)
         {
             foreach (var item in dto.KnowledgeIds)
@@ -503,6 +507,138 @@ namespace Hotline.Api.Controllers
             }
         }
 
+        /// <summary>
+        /// 知识库-记录
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPut("update-and-record")]
+        [LogFilter("知识修改并且保存修改之前的信息")]
+        public async Task UpdateAndRecord([FromBody] UpdateKnowledgeAndApproveDto dto)
+        {
+            // 知识库记录
+            var knowledge = await _knowledgeRepository.Queryable()
+                .Includes(x => x.SourceOrganize)
+                .Includes(x => x.KnowledgeTypes)
+                .Includes(x => x.KnowledgeOrganizes)
+                .Includes(x => x.HotspotType)
+                .FirstAsync(d => d.Id == dto.Id);
+            if (knowledge != null)
+            {
+                var data = _mapper.Map<KnowledgeRecord>(knowledge);
+                data.KnowledgeId = knowledge.Id;
+                data.knowledgeRecordTypeText = knowledge.KnowledgeTypes != null && knowledge.KnowledgeTypes.Any()
+                                               ? string.Join(',', knowledge.KnowledgeTypes.Select(x => x.Name))
+                                               : string.Empty;
+                await _knowledgeRecordRepository.AddNav(data)
+                      .Include(d => d.KnowledgeTypes)
+                      .Include(d => d.KnowledgeOrganizes)
+                      .ExecuteCommandAsync();
+
+                // 知识库修改
+                await _knowledgeDomainService.UpdateKnowledgeAsync(dto, HttpContext.RequestAborted);
+            }
+        }
+
+        /// <summary>
+        /// 知识库-记录
+        /// </summary>
+        /// <param name="Id"></param>
+        /// <returns></returns>
+        [HttpGet("queryRecord/{Id}")]
+        [LogFilter("查询知识库修改记录")]
+        public async Task<object> QueryRecord(string Id)
+        {
+            var queryDto = new KnowledgeDto();
+            var knowledgeDto = new KnowledgeDto();
+
+            var query = await _knowledgeRecordRepository.Queryable()
+                .Includes(x => x.SourceOrganize)
+                .Includes(x => x.KnowledgeTypes)
+                .Includes(x => x.KnowledgeOrganizes)
+                .Includes(x => x.HotspotType)
+                .OrderByDescending(d => d.CreationTime)
+                .FirstAsync(d => d.KnowledgeId == Id, HttpContext.RequestAborted);
+
+            if (query != null)
+            {
+                #region 最新修改记录
+
+                //转化
+                queryDto = _mapper.Map<KnowledgeDto>(query);
+
+                if (queryDto != null && !string.IsNullOrEmpty(queryDto.Content))
+                    queryDto.Content = _bulletinApplication.GetSiteUrls(queryDto.Content);
+
+                //收藏
+                var collect1 = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
+                if (queryDto != null && collect1 != null)
+                    queryDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect1);
+                //关联知识
+                var knowledges1 = await _knowledgeRepository.Queryable().In(x => x.Id, query.Knowledges).Where(x => x.Status == EKnowledgeStatus.OnShelf && ((x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)).ToListAsync();
+                if (queryDto != null && knowledges1.Any())
+                    queryDto.KnowledgeDtos = _mapper.Map<List<KnowledgeDto>>(knowledges1);
+                //关键词
+                var knowledgeWords1 = await _knowledgeWrodRepository.Queryable().In(x => x.Id, query.Keywords).ToListAsync();
+                if (queryDto != null && knowledgeWords1.Any())
+                    queryDto.KeywordsDto = _mapper.Map<List<KnowledgeWordDto>>(knowledgeWords1);
+
+                if (queryDto != null && queryDto.FileJson != null && queryDto.FileJson.Any())
+                {
+                    var ids = queryDto.FileJson.Select(x => x.Id).ToList();
+                    queryDto.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
+                }
+
+                #endregion
+            }
+
+            var knowledge = await _knowledgeRepository.Queryable()
+                .Includes(x => x.SourceOrganize)
+                .Includes(x => x.KnowledgeTypes)
+                .Includes(x => x.KnowledgeOrganizes)
+                .Includes(x => x.HotspotType)
+                .FirstAsync(p => p.Id == Id, HttpContext.RequestAborted);
+            if (knowledge != null)
+            {
+                #region 当前知识库
+
+                //转化
+                knowledgeDto = _mapper.Map<KnowledgeDto>(knowledge);
+
+                if (knowledgeDto != null && !string.IsNullOrEmpty(knowledgeDto.Content))
+                    knowledgeDto.Content = _bulletinApplication.GetSiteUrls(knowledgeDto.Content);
+
+                //收藏
+                var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == Id && x.CreatorId == _sessionContext.UserId);
+                if (knowledgeDto != null && collect != null)
+                    knowledgeDto.Collect = _mapper.Map<KnowledgeCollectDto>(collect);
+                //关联知识
+                var knowledges = await _knowledgeRepository.Queryable().In(x => x.Id, knowledge.Knowledges).Where(x => x.Status == EKnowledgeStatus.OnShelf && ((x.ExpiredTime != null && x.ExpiredTime >= DateTime.Now) || x.ExpiredTime == null)).ToListAsync();
+                if (knowledgeDto != null && knowledges.Any())
+                    knowledgeDto.KnowledgeDtos = _mapper.Map<List<KnowledgeDto>>(knowledges);
+                //关键词
+                var knowledgeWords = await _knowledgeWrodRepository.Queryable().In(x => x.Id, knowledge.Keywords).ToListAsync();
+                if (knowledgeDto != null && knowledgeWords.Any())
+                    knowledgeDto.KeywordsDto = _mapper.Map<List<KnowledgeWordDto>>(knowledgeWords);
+
+                if (knowledgeDto != null && knowledgeDto.FileJson != null && knowledgeDto.FileJson.Any())
+                {
+                    var ids = knowledgeDto.FileJson.Select(x => x.Id).ToList();
+                    knowledgeDto.Files = await _fileRepository.GetFilesAsync(ids, HttpContext.RequestAborted);
+                }
+
+                if (knowledgeDto != null)
+                {
+                    knowledgeDto.knowledgeRecordTypeText = knowledge.KnowledgeTypes != null && knowledge.KnowledgeTypes.Any()
+                                                            ? string.Join(',', knowledge.KnowledgeTypes.Select(x => x.Name))
+                                                            : string.Empty;
+                }
+
+                #endregion
+            }
+            return new { OldInfo = queryDto, NewInfo = knowledgeDto };
+        }
+
         /// <summary>
         /// 批量更新公开状态(new)
         /// </summary>
@@ -618,7 +754,7 @@ namespace Hotline.Api.Controllers
         /// <param name="id"></param>
         /// <returns></returns>
         [HttpDelete]
-        [LogFilter("删除知识")]
+        [LogFilterAlpha("删除知识")]
         public async Task Remove([FromBody] DeleteStartFlowDto dto)
         {
             //var delete = _mapper.Map<KnowledgeDto>(dto.Data);
@@ -645,7 +781,7 @@ namespace Hotline.Api.Controllers
         /// 删除知识(new)
         /// </summary>
         [HttpDelete("remove")]
-        [LogFilter("删除知识")]
+        [LogFilterAlpha("删除知识")]
         public async Task Remove([FromBody] DeleteKnowledgeDto dto)
         {
             var knowledge = await _knowledgeRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -677,7 +813,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPost("search_num")]
-        [LogFilter("知识搜索")]
+        [LogFilterAlpha("知识搜索")]
         public async Task SearchNum([FromBody] KnowledgeSearchNumDto dto)
         {
 
@@ -1384,7 +1520,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dtos"></param>
         /// <returns></returns>
         [HttpPost("knowledge_word")]
-        [LogFilter("新增知识库词库")]
+        [LogFilterAlpha("新增知识库词库")]
         public async Task Add([FromBody] KnowledgeWordAddDto dto)
         {
             var word = _mapper.Map<KnowledgeWord>(dto);
@@ -1397,7 +1533,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpDelete("knowledge_word")]
-        [LogFilter("删除知识库词库")]
+        [LogFilterAlpha("删除知识库词库")]
         public async Task Delete([FromBody] KnowledgeWordDeleteDto dto)
         {
             await _knowledgeRepository.RemoveKnowledgeWrodBatchAsync(dto.Ids, HttpContext.RequestAborted);
@@ -1409,7 +1545,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut("knowledge_word")]
-        [LogFilter("更新知识库词库")]
+        [LogFilterAlpha("更新知识库词库")]
         public async Task Update([FromBody] KnowledgeWordUpdateDto dto)
         {
             var word = await _knowledgeWrodRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -1472,7 +1608,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dtos"></param>
         /// <returns></returns>
         [HttpPost("knowledge_correction")]
-        [LogFilter("新增知识纠错")]
+        [LogFilterAlpha("新增知识纠错")]
         public async Task Add([FromBody] KnowledgeCorrectionAddDto dto)
         {
             var correction = _mapper.Map<KnowledgeCorrection>(dto);
@@ -1511,7 +1647,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut("knowledge_correction/Reply")]
-        [LogFilter("答复知识纠错")]
+        [LogFilterAlpha("答复知识纠错")]
         public async Task Reply([FromBody] KnowledgeCorrectionUpdateDto dto)
         {
             var correction = await _knowledgeCorrectionRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -1572,7 +1708,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dtos"></param>
         /// <returns></returns>
         [HttpPost("knowledge_questions")]
-        [LogFilter("新增知识提问")]
+        [LogFilterAlpha("新增知识提问")]
         public async Task Add([FromBody] KnowledgeQuestionsAddDto dto)
         {
             var questions = _mapper.Map<KnowledgeQuestions>(dto);
@@ -1611,7 +1747,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpPut("knowledge_questions/Reply")]
-        [LogFilter("答复知识提问")]
+        [LogFilterAlpha("答复知识提问")]
         public async Task Reply([FromBody] KnowledgeQuestionsUpdateDto dto)
         {
             var questions = await _knowledgeQuestionsRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -1692,7 +1828,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dtos"></param>
         /// <returns></returns>
         [HttpPost("knowledge_collect")]
-        [LogFilter("知识收藏")]
+        [LogFilterAlpha("知识收藏")]
         public async Task Add([FromBody] KnowledgeCollectAddDto dto)
         {
             var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
@@ -1721,7 +1857,7 @@ namespace Hotline.Api.Controllers
         /// <param name="dto"></param>
         /// <returns></returns>
         [HttpDelete("knowledge_score")]
-        [LogFilter("知识评分")]
+        [LogFilterAlpha("知识评分")]
         public async Task Delete([FromBody] KnowledgeCollectAddDto dto)
         {
             var collect = await _knowledgeCollectRepository.GetAsync(x => x.KnowledgeId == dto.KnowledgeId && x.CreatorId == _sessionContext.UserId);
@@ -2008,7 +2144,17 @@ namespace Hotline.Api.Controllers
 
             var (total, items) = await query.ToPagedListAsync(request, HttpContext.RequestAborted);
 
-            return new PagedDto<KnowledgeApproveDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApproveDto>>(items));
+            var data = _mapper.Map<List<KnowledgeApproveDto>>(items);
+
+            data.ForEach(d =>
+            {
+                if (_knowledgeRecordRepository.Queryable().Where(x => x.KnowledgeId == d.KnowledgeId).Count() > 0)
+                {
+                    d.IsRecord = true;
+                }
+            });
+
+            return new PagedDto<KnowledgeApproveDto>(total, data);
         }
 
         /// <summary>

+ 70 - 64
src/Hotline.Api/Controllers/OrderController.cs

@@ -473,7 +473,7 @@ public class OrderController : BaseController
         //会签件也需支持批量发布;若会签件要批量发布,就默认不公开,只对实际办理部门进行回访即可
         var hasHuiQian = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id) && x.CounterSignType != null);
         //var hasHuiQian = await _orderRepository.Queryable().AnyAsync(x => dto.Ids.Contains(x.Id));
-        if (hasHuiQian)
+        if (hasHuiQian && _appOptions.Value.IsZiGong == false)
             throw UserFriendlyException.SameMessage("选择的工单中含有会签工单, 不能批量发布. 请排除会签工单.");
 
         var hasProvince = false;
@@ -512,7 +512,7 @@ public class OrderController : BaseController
     /// </summary>
     /// <returns></returns>
     [HttpPost("publish")]
-    [LogFilter("发布工单")]
+    [LogFilterAlpha("发布工单")]
     public async Task PublishOrder([FromBody] PublishOrderDto dto)
     {
         //验证订单
@@ -828,6 +828,12 @@ public class OrderController : BaseController
             res.SnapshotLabel = _sysDicDataCacheManager.SnapshotOrderLabel;
         }
 
+        //如果是自贡,需要判断是否是中心会签件,如果是中心会签件,需要查询参与会签的所有一级部门
+        if (_appOptions.Value.IsZiGong && order.FileOrgIsCenter == true && order.CounterSignType == ECounterSignType.Center)
+        {
+            res.CountersignOneOrgList = await _orderDomainService.GetCountersignOneOrg(order.WorkflowId);
+        }
+
         return res;
     }
 
@@ -895,7 +901,7 @@ public class OrderController : BaseController
     /// </summary>
     /// <returns></returns>
     [HttpPost("publish/temp")]
-    [LogFilter("临时发布")]
+    [LogFilterAlpha("临时发布")]
     public async Task PublishTempOrder([FromBody] PublishOrderDto dto)
     {
         //验证订单
@@ -1072,7 +1078,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("published-order-modify")]
-    [LogFilter("修改发布内容")]
+    [LogFilterAlpha("修改发布内容")]
     public async Task PublishedModify([FromBody] PublishOrderModifyDto dto)
     {
         var publishOrder = await _orderPublishRepository.Queryable()
@@ -1192,7 +1198,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("publish/cancel")]
-    [LogFilter("取消发布")]
+    [LogFilterAlpha("取消发布")]
     public async Task<string> PublishCancelAsync([FromBody] PublishCancelInDto dto)
     {
         var enabled = _systemSettingCacheManager.CancelPublishOrderEnabled;
@@ -1592,7 +1598,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("visit/batch")]
-    [LogFilter("批量工单回访")]
+    [LogFilterAlpha("批量工单回访")]
     public async Task<VisitBatchOutDto> VisitBatch([FromBody] VisitBatchInDto dto)
     {
         var errorMessage = new StringBuilder();
@@ -1938,7 +1944,7 @@ public class OrderController : BaseController
     /// <returns></returns>
     /// <exception cref="UserFriendlyException"></exception>
     [HttpPost("visitapply/add")]
-    [LogFilter("新增工单二次回访申请")]
+    [LogFilterAlpha("新增工单二次回访申请")]
     public async Task ApplyOrderVisit([FromBody] AddVisitApplyDto dto)
     {
         var orderVisitApply = _mapper.Map<OrderVisitApply>(dto);
@@ -1975,7 +1981,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("visitapply/examin")]
-    [LogFilter("新增工单二次回访审核")]
+    [LogFilterAlpha("新增工单二次回访审核")]
     public async Task ExaminOrderVisit([FromBody] ExaminOrderVisitDto dto)
     {
         //获取二次回访申请
@@ -2144,7 +2150,7 @@ public class OrderController : BaseController
     ///// 发起重办
     ///// </summary>
     //[HttpPost("redo")]
-    //[LogFilter("新增工单重办")]
+    //[LogFilterAlpha("新增工单重办")]
     //public async Task<string> AddRedo([FromBody] OrderRedoStartFlowDto dto)
     //{
     //    var redo = _mapper.Map<OrderRedo>(dto.Data);
@@ -2224,7 +2230,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("alter_delay_day")]
-    [LogFilter("工单延期修改延期时限")]
+    [LogFilterAlpha("工单延期修改延期时限")]
     public async Task AlterDelayDay([FromBody] AlterDelayDayDto dto)
     {
         if (dto.DelayNum < 1) throw UserFriendlyException.SameMessage("延期申请天数需大于等于1天!");
@@ -2240,7 +2246,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("delay")]
-    [LogFilter("新增工单延期申请")]
+    [LogFilterAlpha("新增工单延期申请")]
     public async Task<string> ApplyDelay([FromBody] StartWorkflowDto<ApplyDelayDto> dto)
     {
         var delaydto = dto.Data;
@@ -2356,7 +2362,7 @@ public class OrderController : BaseController
     /// 工单延期修改后下一步流程
     /// </summary>
     [HttpPost("delay/initial_nextFlow")]
-    [LogFilter("开始工单延期流程")]
+    [LogFilterAlpha("开始工单延期流程")]
     public async Task InitialNextFlow([FromBody] DelayNextFlowDto dto)
     {
         var delay = await _orderDelayRepository.GetAsync(dto.Data.Id);
@@ -2381,7 +2387,7 @@ public class OrderController : BaseController
     /// 批量审批延期
     /// </summary>
     [HttpPost("delay/batch_audit")]
-    [LogFilter("批量审批延期")]
+    [LogFilterAlpha("批量审批延期")]
     //[LogFilterAlpha("延期审核")]
     public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
     {
@@ -2487,7 +2493,7 @@ public class OrderController : BaseController
     }
 
     //[HttpPost("delay/batch_audit")]
-    //[LogFilter("批量审批延期")]
+    //[LogFilterAlpha("批量审批延期")]
     //public async Task<string> BatchAuditDelay([FromBody] BatchDelayNextFlowDto dto)
     //{
     //    var result = new StringBuilder();
@@ -2696,7 +2702,7 @@ public class OrderController : BaseController
     /// <param name="id"></param>
     /// <returns></returns>
     [HttpPost("delay/cancel")]
-    [LogFilter("取消工单延期")]
+    [LogFilterAlpha("取消工单延期")]
     public async Task CancelDelay([FromBody] CancelDelayDto dto)
     {
         var orderDelay =
@@ -3095,7 +3101,7 @@ public class OrderController : BaseController
     /// 开始工单甄别流程
     /// </summary>
     [HttpPost("screen/startflow")]
-    [LogFilter("开始工单甄别流程")]
+    [LogFilterAlpha("开始工单甄别流程")]
     public async Task StartFlow([FromBody] StartWorkflowDto<OrderScreenDto> dto)
     {
         var screenAny = await _orderScreenRepository.AnyAsync(x =>
@@ -3182,7 +3188,7 @@ public class OrderController : BaseController
     /// 工单甄别修改后下一步流程
     /// </summary>
     [HttpPost("screen/initial_nextFlow")]
-    [LogFilter("办理工单甄别流程")]
+    [LogFilterAlpha("办理工单甄别流程")]
     public async Task InitialNextFlow([FromBody] ScreenNextFlowDto dto)
     {
         var screen = await _orderScreenRepository.GetAsync(dto.Data.Id);
@@ -3416,7 +3422,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("order_screen_endtime")]
-    [LogFilter("更新甄别提起截至时限")]
+    [LogFilterAlpha("更新甄别提起截至时限")]
     public async Task Update([FromBody] OrderScreenEndTimeDto dto)
     {
         await _orderVisitedDetailRepository.Updateable().SetColumns(x => new OrderVisitDetail { ScreenByEndTime = dto.ScreenByEndTime })
@@ -3429,7 +3435,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("order_screen_alter")]
-    [LogFilter("更新甄别信息")]
+    [LogFilterAlpha("更新甄别信息")]
     public async Task Update([FromBody] OrderScreenAlterDto dto)
     {
         var screen = await _orderScreenRepository.GetAsync(dto.ScreenId);
@@ -3731,7 +3737,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("supervise/apply")]
-    [LogFilter("新增工单督办")]
+    [LogFilterAlpha("新增工单督办")]
     public async Task ApplySupervise([FromBody] ApplyOrderSuperviseDto dto)
     {
         if (!dto.SuperviseOrgDtos.Any())
@@ -3865,7 +3871,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("supervise/reply")]
-    [LogFilter("回复工单督办")]
+    [LogFilterAlpha("回复工单督办")]
     public async Task ReplySupervise([FromBody] ReplyOrderSuperviseDto dto)
     {
         //验证是否存在督办
@@ -3917,7 +3923,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("supervise/sign")]
-    [LogFilter("签收工单督办")]
+    [LogFilterAlpha("签收工单督办")]
     public async Task SignSupervise([FromBody] SignOrderSuperviseDto dto)
     {
         //验证是否存在督办
@@ -4086,7 +4092,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("urge/add")]
-    [LogFilter("批量催办工单")]
+    [LogFilterAlpha("批量催办工单")]
     public async Task UrgeAdd([FromBody] OrderUrgeAddDto dto)
     {
         if (dto is null)
@@ -4211,7 +4217,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("urge/apply")]
-    [LogFilter("新增工单催办")]
+    [LogFilterAlpha("新增工单催办")]
     public async Task ApplyUrge([FromBody] ApplyOrderUrgeDto dto)
     {
         if (!dto.UrgeOrgDtos.Any())
@@ -4338,7 +4344,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("urge/reply")]
-    [LogFilter("回复工单催办")]
+    [LogFilterAlpha("回复工单催办")]
     public async Task ReplyUrge([FromBody] ReplyOrderUrgeDto dto)
     {
         //验证是否存在催办
@@ -4367,7 +4373,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("urge/sign")]
-    [LogFilter("签收工单催办")]
+    [LogFilterAlpha("签收工单催办")]
     public async Task SignUrge([FromBody] SignOrderUrgeDto dto)
     {
         //验证是否存在催办
@@ -4601,7 +4607,7 @@ public class OrderController : BaseController
         //随手拍
         if (_systemSettingCacheManager.Snapshot)
         {
-            query = query.WhereIF(dto.IndustryId.NotNullOrEmpty(),  d => d.OrderSnapshot.IndustryId == dto.IndustryId);
+            query = query.WhereIF(dto.IndustryId.NotNullOrEmpty(), d => d.OrderSnapshot.IndustryId == dto.IndustryId);
             query = query.WhereIF(dto.IsSnapshot.HasValue && dto.IsSnapshot.Value == true, d => d.OrderSnapshot.Id != null);
         }
 
@@ -5269,7 +5275,7 @@ public class OrderController : BaseController
     /// </summary>
     [HttpPost("add-anonymous")]
     [AllowAnonymous]
-    [LogFilter("省平台调用记录")]
+    [LogFilterAlpha("省平台调用记录")]
     public async Task<AddOrderResponse> AddAnonymous([FromBody] AddOrderDto dto)
     {
         return await _orderApplication.ReceiveOrderFromExternalAsync(dto, HttpContext.RequestAborted);
@@ -5308,7 +5314,7 @@ public class OrderController : BaseController
     /// <param name="id"></param>
     /// <returns></returns>
     [HttpDelete("{id}")]
-    [LogFilter("删除工单")]
+    [LogFilterAlpha("删除工单")]
     public async Task Remove(string id)
     {
         var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
@@ -5324,7 +5330,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut]
-    [LogFilter("更新工单")]
+    [LogFilterAlpha("更新工单")]
     public async Task<object> Update([FromBody] UpdateOrderDto dto)
     {
         dto.InitAddress();
@@ -6642,7 +6648,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("list/file_upload")]
-    [LogFilter("附件列表补充附件")]
+    [LogFilterAlpha("附件列表补充附件")]
     public async Task Add([FromBody] OrderStepUploadFilesDto dto)
     {
         var order = await _orderRepository.GetAsync(dto.OrderId);
@@ -7391,7 +7397,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("send_back/apply")]
-    [LogFilter("新增工单退回申请")]
+    [LogFilterAlpha("新增工单退回申请")]
     public async Task ApplyUrge([FromBody] OrderSendBackAddDto dto)
     {
         //验证工单是否可以申请
@@ -7430,7 +7436,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("send_back/audit")]
-    [LogFilter("审核工单退回申请")]
+    [LogFilterAlpha("审核工单退回申请")]
     public async Task ReplyUrge([FromBody] AuditOrderSendBackDto dto)
     {
         //验证是否存在退回
@@ -7488,7 +7494,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("special")]
-    [LogFilter("新增工单特提")]
+    [LogFilterAlpha("新增工单特提")]
     [LogFilterAlpha("特提审核")]
     public async Task Add([FromBody] OrderSpecialAddDto dto)
     {
@@ -7681,7 +7687,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPost("re_transact")]
-    [LogFilter("工单重办")]
+    [LogFilterAlpha("工单重办")]
     public async Task Add([FromBody] OrderReTransactDto dto)
     {
         var order = await _orderRepository
@@ -7930,7 +7936,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("special")]
-    [LogFilter("审批工单特提")]
+    [LogFilterAlpha("审批工单特提")]
     public async Task Update([FromBody] AuditOrderSpecialDto dto)
     {
         var special = await _orderSpecialRepository
@@ -8014,7 +8020,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPut("special_batch")]
-    [LogFilter("批量审批工单特提")]
+    [LogFilterAlpha("批量审批工单特提")]
     [LogFilterAlpha("特提审核批量")]
     public async Task UpdateBatch([FromBody] BatchAuditOrderSpecialDto dto)
     {
@@ -8627,7 +8633,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("citizen")]
-    [LogFilter("新增市民信息")]
+    [LogFilterAlpha("新增市民信息")]
     public async Task Add([FromBody] CitizenAddDto dto)
     {
         var citizen =
@@ -8643,7 +8649,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpDelete("citizen")]
-    [LogFilter("删除市民信息")]
+    [LogFilterAlpha("删除市民信息")]
     public async Task Delete([FromBody] CitizenDeleteDto dto)
     {
         await _citizenRepository.RemoveAsync(x => x.Id == dto.Id);
@@ -8655,7 +8661,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("citizen")]
-    [LogFilter("更新市民信息")]
+    [LogFilterAlpha("更新市民信息")]
     public async Task Update([FromBody] CitizenUpdateDto dto)
     {
         var citizen = await _citizenRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -8857,7 +8863,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("repeatable_event")]
-    [LogFilter("新增重复性事件")]
+    [LogFilterAlpha("新增重复性事件")]
     public async Task Add([FromBody] RepeatableEventAddDto dto)
     {
         var repeatable = _mapper.Map<RepeatableEvent>(dto);
@@ -8876,7 +8882,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpDelete("repeatable_event")]
-    [LogFilter("删除重复性事件")]
+    [LogFilterAlpha("删除重复性事件")]
     public async Task Delete([FromBody] RepeatableEventDeleteDto dto)
     {
         await _repeatableEventRepository.RemoveAsync(x => x.Id == dto.Id);
@@ -8889,7 +8895,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpDelete("repeatable_event_detail/{id}")]
-    [LogFilter("删除重复性事件")]
+    [LogFilterAlpha("删除重复性事件")]
     public async Task Delete([FromBody] string id)
     {
         await _repeatableEventDetailRepository.RemoveAsync(x => x.Id == id);
@@ -8901,7 +8907,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("repeatable_event")]
-    [LogFilter("更新重复性事件")]
+    [LogFilterAlpha("更新重复性事件")]
     public async Task Update([FromBody] RepeatableEventUpdateDto dto)
     {
         var repeatable = await _repeatableEventRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -8969,7 +8975,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("order_word")]
-    [LogFilter("新增工单词库")]
+    [LogFilterAlpha("新增工单词库")]
     public async Task Add([FromBody] OrderWordAddDto dto)
     {
         var word = _mapper.Map<OrderWord>(dto);
@@ -8985,7 +8991,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpDelete("order_word")]
-    [LogFilter("删除工单词库")]
+    [LogFilterAlpha("删除工单词库")]
     public async Task Delete([FromBody] OrderWordDeleteDto dto)
     {
         await _orderRepository.RemoveOrderWrodBatchAsync(dto.Ids, HttpContext.RequestAborted);
@@ -8997,7 +9003,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("order_word")]
-    [LogFilter("更新工单词库")]
+    [LogFilterAlpha("更新工单词库")]
     public async Task Update([FromBody] OrderWordUpdateDto dto)
     {
         var word = await _orderWrodRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -9100,7 +9106,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("order_observe")]
-    [LogFilter("新增工单观察")]
+    [LogFilterAlpha("新增工单观察")]
     public async Task Add([FromBody] OrderObserveAddDto dto)
     {
         var ids = dto.OrderIds.Select(x => x.OrderId).ToList();
@@ -9120,7 +9126,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpDelete("order_observe")]
-    [LogFilter("删除工单观察")]
+    [LogFilterAlpha("删除工单观察")]
     public async Task Delete([FromBody] OrderObserveDeleteDto dto)
     {
         await _orderRepository.RemoveOrderObserveBatchAsync(dto.Ids, HttpContext.RequestAborted);
@@ -9132,7 +9138,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("order_observe")]
-    [LogFilter("更新工单观察")]
+    [LogFilterAlpha("更新工单观察")]
     public async Task Update([FromBody] OrderObserveUpdateDto dto)
     {
         var word = await _orderObserveRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -9227,7 +9233,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("order_finality")]
-    [LogFilter("新增工单终结")]
+    [LogFilterAlpha("新增工单终结")]
     public async Task Add([FromBody] OrderFinalityAddDto dto)
     {
         var ids = dto.OrderIds.Select(x => x.OrderId).ToList();
@@ -9247,7 +9253,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpDelete("order_finality")]
-    [LogFilter("删除工单终结")]
+    [LogFilterAlpha("删除工单终结")]
     public async Task Delete([FromBody] OrderFinalityDeleteDto dto)
     {
         await _orderRepository.RemoveOrderFinalityBatchAsync(dto.Ids, HttpContext.RequestAborted);
@@ -9259,7 +9265,7 @@ public class OrderController : BaseController
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpPut("order_finality")]
-    [LogFilter("更新工单终结")]
+    [LogFilterAlpha("更新工单终结")]
     public async Task Update([FromBody] OrderFinalityUpdateDto dto)
     {
         var word = await _orderFinalityRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
@@ -9474,7 +9480,7 @@ public class OrderController : BaseController
     /// 工单签收
     /// </summary>
     [HttpPost("sign/{orderId}")]
-    [LogFilter("工单签收")]
+    [LogFilterAlpha("工单签收")]
     public async Task Sign(string orderId)
     {
         var order = await _orderRepository.GetAsync(orderId, HttpContext.RequestAborted);
@@ -9741,7 +9747,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("secondary_handling")]
-    [LogFilter("新增二次办理")]
+    [LogFilterAlpha("新增二次办理")]
     public async Task OrderSecondaryHandlingAdd([FromBody] AddOrderSecondaryHandlingDto dto)
     {
         await _orderSecondaryHandlingApplication.AddAsync(dto, HttpContext.RequestAborted);
@@ -9754,7 +9760,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("secondary_handling/send_back")]
-    [LogFilter("二次办理退回")]
+    [LogFilterAlpha("二次办理退回")]
     public async Task OrderSecondaryHandlingSendBackAsync([FromBody] SendBackOrderSecondaryHandlingDto dto)
     {
         await _orderSecondaryHandlingApplication.SendBackAsync(dto, HttpContext.RequestAborted);
@@ -9766,7 +9772,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPut("secondary_handling/audit")]
-    [LogFilter("二次办理审批")]
+    //[LogFilterAlpha("二次办理审批")]
     [LogFilterAlpha("二次办理审核")]
     public async Task OrderSecondaryHandlingAudit([FromBody] AuditOrderSecondaryHandlingDto dto)
     {
@@ -9782,7 +9788,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPut("secondary_handling/batch_audit")]
-    [LogFilter("二次办理批量审批")]
+    //[LogFilterAlpha("二次办理批量审批")]
     [LogFilterAlpha("二次办理审核批量")]
     public async Task OrderSecondaryHandlingBatchAudit([FromBody] AuditOrderSecondaryHandlingDto dto)
     {
@@ -10369,7 +10375,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPost("analysis")]
-    [LogFilter("新增分析报告")]
+    [LogFilterAlpha("新增分析报告")]
     public async Task OrderAnalysisAdd([FromBody] AddOrderAnalysisDto dto)
     {
         await _orderAnalysisApplication.AddAsync(dto, HttpContext.RequestAborted);
@@ -10381,7 +10387,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpPut("analysis")]
-    [LogFilter("修改分析报告")]
+    [LogFilterAlpha("修改分析报告")]
     public async Task OrderAnalysisUpdate([FromBody] UpdateOrderAnalysisDto dto)
     {
         await _orderAnalysisApplication.UpdateAsync(dto, HttpContext.RequestAborted);
@@ -10393,7 +10399,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpDelete("analysis")]
-    [LogFilter("删除分析报告")]
+    [LogFilterAlpha("删除分析报告")]
     public async Task OrderAnalysisDelete([FromBody] DeleteOrderAnalysisDto dto)
     {
         await _orderAnalysisApplication.DeleteAsync(dto, HttpContext.RequestAborted);
@@ -10405,7 +10411,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpGet("analysis_list")]
-    [LogFilter("分析报告列表")]
+    [LogFilterAlpha("分析报告列表")]
     public async Task<PagedDto<OrderAnalysisDto>> OrderAnalysisListQuery([FromQuery] OrderAnalysisListDto dto)
     {
         var (total, items) = await _orderAnalysisApplication.ListQuery(dto, HttpContext.RequestAborted)
@@ -10419,7 +10425,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpGet("analysis_detail")]
-    [LogFilter("分析报告明细")]
+    [LogFilterAlpha("分析报告明细")]
     public async Task<PagedDto<OrderDto>> OrderAnalysisDetailQuery([FromQuery] OrderAnalysisDetailDto dto)
     {
         var (total, items) = await _orderAnalysisApplication.DetailQuery(dto, HttpContext.RequestAborted)
@@ -10433,7 +10439,7 @@ public class OrderController : BaseController
     /// <param name="dtos"></param>
     /// <returns></returns>
     [HttpGet("analysis_report")]
-    [LogFilter("生成分析报告")]
+    [LogFilterAlpha("生成分析报告")]
     public async Task<object> OrderAnalysisReportQuery([FromQuery] OrderAnalysisDetailDto dto)
     {
         return await _orderAnalysisApplication.ReportQuery(dto, HttpContext.RequestAborted);

+ 11 - 2
src/Hotline.Api/Controllers/OrderRevocationController.cs

@@ -187,6 +187,13 @@ namespace Hotline.Api.Controllers
                                 order.ActualHandleTime = DateTime.Now;
                                 order.ActualHandlerId = _sessionContext.UserId;
 
+                                //自贡任务 579 设置撤销件后该工单需处理成中心归档非会签件
+                                if (_appOptions.Value.IsZiGong)
+                                {
+                                    order.CounterSignType = null;
+                                    order.FileOrgIsCenter = true;
+                                }
+
                                 await _orderRepository.Updateable(order).UpdateColumns(it => new
                                 {
                                     it.ActualHandleOrgName,
@@ -197,8 +204,10 @@ namespace Hotline.Api.Controllers
                                     it.ActualHandleOrgAreaName,
                                     it.ActualHandlerName,
                                     it.ActualHandleTime,
-                                    it.ActualHandlerId
-                                }).ExecuteCommandAsync();
+                                    it.ActualHandlerId,
+                                    it.CounterSignType,
+                                    it.FileOrgIsCenter
+                                }).ExecuteCommandAsync(HttpContext.RequestAborted);
 
                                 #endregion
 

+ 1 - 1
src/Hotline.Application/Handlers/FlowEngine/WorkflowEndHandler.cs

@@ -204,7 +204,7 @@ public class WorkflowEndHandler : INotificationHandler<EndWorkflowNotify>
                     order.FileUserOrgName = notification.Trace.HandlerOrgName;
                     order.FileOrgIsCenter = notification.Trace.HandlerOrgIsCenter;
                     order.FileOpinion = notification.Dto.Opinion;
-                    
+
                     /*
                      *需求:
                      *1、判断工单属于哪种归档类型,需由谁归档来判断,热线中心归档的就叫中心归档件,部门归档就叫做部门归档件

+ 6 - 1
src/Hotline.Application/OrderApp/Handlers/OrderDelayHandler/OrderDelayBatchReviewTaskCompetedHandler.cs

@@ -13,6 +13,7 @@ using Hotline.Orders;
 using Hotline.Share.Dtos.Article;
 using Hotline.Share.Enums.Article;
 using Hotline.Share.Enums.Order;
+using Microsoft.Extensions.Logging;
 using XF.Domain.Authentications;
 using XF.Domain.Repository;
 
@@ -26,15 +27,18 @@ public class OrderDelayBatchReviewTaskCompetedHandler : INotificationHandler<App
     private readonly IRepository<Apptask> _apptaskRepository;
     private readonly IOrderDelayRepository _orderDelayRepository;
     private readonly ICircularRecordDomainService _circularRecordDomainService;
+    private readonly ILogger<OrderDelayBatchReviewTaskCompetedHandler> _logger;
 
     public OrderDelayBatchReviewTaskCompetedHandler(
         IRepository<Apptask> apptaskRepository,
         IOrderDelayRepository orderDelayRepository,
-        ICircularRecordDomainService circularRecordDomainService)
+        ICircularRecordDomainService circularRecordDomainService,
+        ILogger<OrderDelayBatchReviewTaskCompetedHandler> logger)
     {
         _apptaskRepository = apptaskRepository;
         _orderDelayRepository = orderDelayRepository;
         _circularRecordDomainService = circularRecordDomainService;
+        _logger = logger;
     }
 
     /// <summary>Handles a notification</summary>
@@ -47,6 +51,7 @@ public class OrderDelayBatchReviewTaskCompetedHandler : INotificationHandler<App
         var apptask = await _apptaskRepository.Queryable()
             .Includes(d => d.ApptaskItems)
             .FirstAsync(d => d.Id == notification.ApptaskItem.ApptaskId, cancellationToken);
+        _logger.LogInformation("批量延期审批任务执行完毕:{name}", apptask.Name);
         var unSuccessItems = apptask.ApptaskItems
             .Where(d => d.TaskStatus != ETaskStatus.Succeeded)
             .ToList();

+ 4 - 2
src/Hotline.Application/OrderApp/OrderApplication.cs

@@ -1418,7 +1418,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             if (order.DuplicateIds != null)
             {
                 order.DuplicateIds.Add(dto.Data.DuplicateId);
-            }else
+            }
+            else
             {
                 order.DuplicateIds = new List<string>() { dto.Data.DuplicateId };
             }
@@ -1465,7 +1466,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 No = visit.No,
                 OrderId = visit.OrderId,
                 ObserveOrgId = visit.Order.ActualHandleOrgCode,
-                State = EDelayState.Examining
+                State = EAduitState.Examining
             };
             await _observationPieceRepository.AddAsync(observationPiece, cancellationToken);
         }
@@ -4706,6 +4707,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .OrderByIF(dto is { SortField: "visitTime", SortRule: 0 }, d => d.VisitTime, OrderByType.Asc) // 回访时间升序
             .OrderByIF(dto is { SortField: "visitTime", SortRule: 1 }, d => d.VisitTime, OrderByType.Desc) // 回访时间升序
             .OrderByIF(_appOptions.Value.IsZiGong && string.IsNullOrEmpty(dto.SortField), d => d.PublishTime, OrderByType.Desc)
+            .WhereIF(!string.IsNullOrEmpty(dto.ContentRetrieval), d => d.Order.Content.Contains(dto.ContentRetrieval!))
             ;
         return query;
     }

+ 5 - 0
src/Hotline.Share/Dtos/Knowledge/KnowledgeApproveDto.cs

@@ -70,5 +70,10 @@ namespace Hotline.Share.Dtos.Knowledge
         /// 审批人
         /// </summary>
         public UserDto Approver { get; set; }
+
+        /// <summary>
+        /// 是否存在知识修改记录
+        /// </summary>
+        public bool? IsRecord { get; set; } = false;
     }
 }

+ 5 - 0
src/Hotline.Share/Dtos/Knowledge/KnowledgeDto.cs

@@ -289,6 +289,11 @@ namespace Hotline.Share.Dtos.Knowledge
         /// 上架时间
         /// </summary>
         public DateTime? OnShelfTime { get; set; }
+
+        /// <summary>
+        /// 知识库记录分类值
+        /// </summary>
+        public string? knowledgeRecordTypeText { get; set; }
     }
 
     public class KnowledgeBaseDto

+ 4 - 0
src/Hotline.Share/Dtos/Order/OrderVisitDto.cs

@@ -158,6 +158,10 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public bool? IsEmployeeNameNull { get; set; }
 
+        /// <summary>
+        /// 受理内容
+        /// </summary>
+        public string? ContentRetrieval { get; set; }
     }
 
     public record QueryOrderVisitListDto : QueryOrderVisitDto

+ 5 - 0
src/Hotline.Share/Dtos/Order/PublishedDto.cs

@@ -194,6 +194,11 @@ public class PublishOrderPageBaseDto
     /// 省工单是否可以选择意愿是否公开
     /// </summary>
     public bool IsProvincePublic { get; set; } = false;
+
+    /// <summary>
+    /// 中心会签,办理的一级部门
+    /// </summary>
+    public List<Kv>? CountersignOneOrgList { get; set; }
 }
 
 public class PublishPublishOrderDto

+ 34 - 0
src/Hotline.Share/Enums/Order/EAduitState.cs

@@ -0,0 +1,34 @@
+using System.ComponentModel;
+
+namespace Hotline.Share.Enums.Order
+{
+    /// <summary>
+    /// 通用审批状态
+    /// </summary>
+    public enum EAduitState
+    {
+        /// <summary>
+        /// 审批中
+        /// </summary>
+        [Description("审批中")]
+        Examining = 0,
+
+        /// <summary>
+        /// 通过
+        /// </summary>
+        [Description("通过")]
+        Pass = 1,
+
+        /// <summary>
+        /// 拒绝
+        /// </summary>
+        [Description("拒绝")]
+        NoPass = 2,
+
+        /// <summary>
+        /// 撤销
+        /// </summary>
+        [Description("撤销")]
+        Withdraw = 3,
+    }
+}

+ 4 - 4
src/Hotline/BatchTask/ApptaskDomainService.cs

@@ -97,9 +97,9 @@ public class ApptaskDomainService : IApptaskDomainService, IScopeDependency
     public async Task<bool> IsCompletedAsync(string taskId, CancellationToken cancellation)
     {
         var anyUnCompleted = await _apptaskItemRepository.Queryable()
-            .AnyAsync(d => d.Tries < d.TryLimit
-                           && (d.TaskStatus == ETaskStatus.Waiting || d.TaskStatus == ETaskStatus.Processing)
-                           && d.ApptaskId == taskId, cancellation);
+            .AnyAsync(d => d.ApptaskId == taskId
+                           && (d.TaskStatus == ETaskStatus.Waiting || d.TaskStatus == ETaskStatus.Failed)
+                           && d.Tries < d.TryLimit, cancellation);
         return !anyUnCompleted;
     }
 
@@ -179,7 +179,7 @@ public class ApptaskDomainService : IApptaskDomainService, IScopeDependency
                 throw new UserFriendlyException($"任务参数反序列化失败, taskItemId: {apptaskItem.Id}");
 
             _sessionContextManager.ChangeSessionContext(request.SessionContext);
-            
+
             //if (request is IApptaskRequest reqWithSession)
             //    _sessionContextProvider.ChangeSession(reqWithSession.SessionContext);
             var result = await executor.ExecuteAsync(request, cancellation);

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

@@ -128,5 +128,7 @@ namespace Hotline.Caching.Interfaces
         bool IsNoPushCallNativeOutNoFile { get; }
 
         bool IsSendDissatisfiedScreenSms { get; }
+
+        bool IsReplayLoginCheck { get; }
     }
 }

+ 2 - 0
src/Hotline/Caching/Services/SystemSettingCacheManager.cs

@@ -256,5 +256,7 @@ namespace Hotline.Caching.Services
 
         public bool IsSendDissatisfiedScreenSms => GetOrDefault("08db29ad-9b54-44ca-8d4d-35c032748040", SettingConstants.IsSendDissatisfiedScreenSms, "回访不满意是否发送甄别短信", true, "true:发送;false:不发送");
 
+        public bool IsReplayLoginCheck => GetOrDefault("08dd92c7-7600-4a83-83c7-87eff77a3e29", SettingConstants.IsReplayLoginCheck, "防登录重放校验", false, "true:启用;false:不启用");
+
     }
 }

+ 25 - 0
src/Hotline/KnowledgeBase/KnowledgeRecord.cs

@@ -0,0 +1,25 @@
+using SqlSugar;
+using System.ComponentModel;
+
+namespace Hotline.KnowledgeBase
+{
+    /// <summary>
+    /// 知识库记录
+    /// </summary>
+    [Description("知识库记录")]
+    public class KnowledgeRecord : Knowledge
+    {
+        /// <summary>
+        /// 知识ID
+        /// </summary>
+        [SugarColumn(ColumnDescription = "知识ID")]
+        public string KnowledgeId { get; set; }
+
+
+        /// <summary>
+        /// 知识记录分类值
+        /// </summary>
+        [SugarColumn(ColumnDescription = "知识记录分类值", ColumnDataType = "varchar(2000)")]
+        public string knowledgeRecordTypeText { get; set; }
+    }
+}

+ 34 - 29
src/Hotline/Orders/IOrderDomainService.cs

@@ -1,9 +1,7 @@
-using Hotline.FlowEngine.Definitions;
-using Hotline.Schedulings;
-using Hotline.Share.Dtos.FlowEngine;
+using Hotline.Schedulings;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
-using Hotline.Share.Enums.FlowEngine;
 
 namespace Hotline.Orders
 {
@@ -73,11 +71,11 @@ namespace Hotline.Orders
         /// <param name="UserId"></param>
         /// <returns></returns>
         Task<bool> SchedulingAtWork(string UserId);
-		/// <summary>
-		/// 平均派单
-		/// </summary>
-		/// <returns></returns>
-		Task<StepAssignInfo> AverageOrder(CancellationToken cancellationToken);
+        /// <summary>
+        /// 平均派单
+        /// </summary>
+        /// <returns></returns>
+        Task<StepAssignInfo> AverageOrder(CancellationToken cancellationToken);
 
         /// <summary>
         /// 登录平均派单
@@ -92,20 +90,20 @@ namespace Hotline.Orders
         /// <returns></returns>
         Task TriggerAverageOrder(CancellationToken cancellationToken);
 
-		/// <summary>
-		/// 提前触发平均派单
-		/// </summary>
-		/// <param name="cancellationToken"></param>
-		/// <returns></returns>
-		Task AdvancedTriggerAverageOrder(CancellationToken cancellationToken);
-		#endregion
-
-		#region  工单校验- 交通类工单
-		/// <summary>
-		/// 工单校验  - 交通类工单
-		/// </summary>
-		/// <returns></returns>
-		Task<OrderValidation> OrderValidation(AddOrderDto dto, CancellationToken cancellationToken);
+        /// <summary>
+        /// 提前触发平均派单
+        /// </summary>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        Task AdvancedTriggerAverageOrder(CancellationToken cancellationToken);
+        #endregion
+
+        #region  工单校验- 交通类工单
+        /// <summary>
+        /// 工单校验  - 交通类工单
+        /// </summary>
+        /// <returns></returns>
+        Task<OrderValidation> OrderValidation(AddOrderDto dto, CancellationToken cancellationToken);
         #endregion
 
         /// <summary>
@@ -130,11 +128,18 @@ namespace Hotline.Orders
         /// <returns></returns>
         Task VisitNoneByCancelPublishAsync(string orderId, CancellationToken cancellationToken);
 
-		/// <summary>
-		/// 计算甄别申请截至日期
-		/// </summary>
-		/// <returns></returns>
-		Task<DateTime> GetScreenByEndTime();
+        /// <summary>
+        /// 计算甄别申请截至日期
+        /// </summary>
+        /// <returns></returns>
+        Task<DateTime> GetScreenByEndTime();
+
+        /// <summary>
+        /// 查询中心最后一次会签的所有一级部门
+        /// </summary>
+        /// <param name="workFlowId"></param>
+        /// <returns></returns>
+        Task<List<Kv>> GetCountersignOneOrg(string workFlowId);
 
-	}
+    }
 }

+ 1 - 1
src/Hotline/Orders/ObservationPiece.cs

@@ -40,7 +40,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 审批状态
         /// </summary>
-        public EDelayState State { get; set; }
+        public EAduitState State { get; set; }
 
         /// <summary>
         /// 审批时间

+ 201 - 151
src/Hotline/Orders/OrderDomainService.cs

@@ -1,49 +1,40 @@
 using DotNetCore.CAP;
 using Hotline.Caching.Interfaces;
-using Hotline.Share.Dtos.Order;
-using Hotline.Share.Enums.Order;
-using MapsterMapper;
-using Microsoft.Extensions.Logging;
-using XF.Domain.Authentications;
-using XF.Domain.Cache;
-using XF.Domain.Dependency;
-using XF.Domain.Exceptions;
-using XF.Domain.Repository;
 using Hotline.CallCenter.Calls;
+using Hotline.Configurations;
+using Hotline.ContingencyManagement.Notifies;
+using Hotline.EventBus;
 using Hotline.File;
 using Hotline.FlowEngine.Workflows;
+using Hotline.Push.Notifies;
 using Hotline.Schedulings;
 using Hotline.SeedData;
-using Hotline.Users;
-using Hotline.Share.Dtos;
+using Hotline.Settings;
 using Hotline.Settings.Hotspots;
+using Hotline.Settings.TimeLimitDomain;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.FlowEngine;
-using Microsoft.AspNetCore.Http;
-using Hotline.Settings;
-using SqlSugar;
-using Hotline.Push.Notifies;
-using Hotline.Share.Enums.Push;
-using MediatR;
-using Hotline.Authentications;
-using Hotline.ContingencyManagement.Notifies;
-using Hotline.EventBus;
-using Hotline.Share.Enums.FlowEngine;
-using Mapster;
-using Microsoft.AspNetCore.Builder.Extensions;
-using Hotline.Configurations;
-using Microsoft.Extensions.Options;
-using Hotline.Share.Tools;
-using Hotline.Orders.Notifications;
-using Hotline.Share.Mq;
-using System.Security.Cryptography;
-using Hotline.FlowEngine.Definitions;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
+using Hotline.Share.Dtos.Order;
+using Hotline.Share.Enums.FlowEngine;
+using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Push;
 using Hotline.Share.Enums.Settings;
-using Hotline.Settings.TimeLimitDomain;
+using Hotline.Share.Mq;
+using Hotline.Share.Tools;
 using Hotline.Snapshot.IRepository;
-using Hotline.Share.Dtos.Push;
-using System.Threading;
-using XF.Domain.Entities;
+using Hotline.Users;
+using Mapster;
+using MapsterMapper;
+using MediatR;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using SqlSugar;
+using XF.Domain.Authentications;
+using XF.Domain.Cache;
+using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
+using XF.Domain.Repository;
 
 namespace Hotline.Orders;
 
@@ -76,9 +67,9 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     private readonly ICalcExpireTime _expireTime;
     private readonly ICallDomainService _callDomainService;
     private readonly IOrderVisitDomainService _orderVisitDomainService;
-	
+    private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
 
-	public OrderDomainService(
+    public OrderDomainService(
         IOrderRepository orderRepository,
         IRepository<OrderRedo> orderRedoRepository,
         IRepository<OrderPublish> orderPublishRepository,
@@ -106,7 +97,8 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         IOrderSnapshotRepository orderSnapshotRepository,
         ICalcExpireTime expireTime,
         ICallDomainService callDomainService,
-        IOrderVisitDomainService orderVisitDomainService)
+        IOrderVisitDomainService orderVisitDomainService,
+        IRepository<WorkflowTrace> workflowTraceRepository)
     {
         _orderRepository = orderRepository;
         _orderRedoRepository = orderRedoRepository;
@@ -135,7 +127,8 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         _expireTime = expireTime;
         _callDomainService = callDomainService;
         _orderVisitDomainService = orderVisitDomainService;
-	}
+        _workflowTraceRepository = workflowTraceRepository;
+    }
 
     /// <summary>
     /// 归档后自动发布
@@ -259,7 +252,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         if (isReturn == false)
         {
             //order.FocusOnEvents!="7" 2025年4月29日 10:55:38 刘欣 临时新增,如果是旅游件不自动回访
-            if (order is { FileOrgIsCenter: true, CounterSignType: null } && !order.IsProvince && order.FocusOnEvents!="7")
+            if (order is { FileOrgIsCenter: true, CounterSignType: null } && !order.IsProvince && order.FocusOnEvents != "7")
             {
                 orderVisit.VisitState = EVisitState.Visited;
                 orderVisit.VisitTime = DateTime.Now;
@@ -289,37 +282,64 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
             VisitId = visitId,
             VisitTarget = EVisitTarget.Seat
         };
-
-        //部门回访明细
-        var orgDetail = new OrderVisitDetail
-        {
-            VisitId = visitId,
-            VisitOrgCode = order.ActualHandleOrgCode,
-            VisitOrgName = order.ActualHandleOrgName,
-            VisitTarget = EVisitTarget.Org
-        };
-
-        if (isReturn == false)
+        //中心会签件,批量发布时,默认不公开,需回访部门需默认勾选会签的所有一级部门(不勾选热线中心)
+        //部门会签件,批量发布时,默认不公开,需回访部门处不勾选部门,只对实际办理部门进行回访
+        if (_appOptions.Value.IsZiGong && order.CounterSignType == ECounterSignType.Center)
         {
-            //order.FocusOnEvents!="7" 2025年4月29日 10:55:38 刘欣 临时新增,如果是旅游件不自动回访
-            if (order is { FileOrgIsCenter: true, CounterSignType: null, IsProvince: false } && order.FocusOnEvents != "7")
+            //查询所有参与会签的一级部门
+            //然后写入回访表
+            var orgList = await GetCountersignOneOrg(order.WorkflowId);
+            if (orgList != null && orgList.Any())
             {
-                var satisfy = new Kv() { Key = "4", Value = "满意" };
-                orgDetail.OrgProcessingResults = satisfy;
-                //orgDetail.OrgHandledAttitude = satisfy;
+                foreach (var item in orgList)
+                {
+                    //部门回访明细
+                    visitedDetail.Add(new OrderVisitDetail
+                    {
+                        VisitId = visitId,
+                        VisitOrgCode = item.Key,
+                        VisitOrgName = item.Value,
+                        VisitTarget = EVisitTarget.Org
+                    });
+                }
             }
+        }
+        else
+        {
+            //部门回访明细
+            var orgDetail = new OrderVisitDetail
+            {
+                VisitId = visitId,
+                VisitOrgCode = order.ActualHandleOrgCode,
+                VisitOrgName = order.ActualHandleOrgName,
+                VisitTarget = EVisitTarget.Org
+            };
 
-            if (order is { FileOrgIsCenter: true, CounterSignType: null })
+            if (isReturn == false)
             {
-                seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
-                seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
-                order.Visited("4", "满意");
-                order.Status = EOrderStatus.Visited;
-                await _orderRepository.UpdateAsync(order, cancellationToken);
+                //order.FocusOnEvents!="7" 2025年4月29日 10:55:38 刘欣 临时新增,如果是旅游件不自动回访
+                if (order is { FileOrgIsCenter: true, CounterSignType: null, IsProvince: false } && order.FocusOnEvents != "7")
+                {
+                    var satisfy = new Kv() { Key = "4", Value = "满意" };
+                    orgDetail.OrgProcessingResults = satisfy;
+                    //orgDetail.OrgHandledAttitude = satisfy;
+                }
+
+                if (order is { FileOrgIsCenter: true, CounterSignType: null })
+                {
+                    seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
+                    seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
+                    order.Visited("4", "满意");
+                    order.Status = EOrderStatus.Visited;
+                    await _orderRepository.UpdateAsync(order, cancellationToken);
+                }
             }
+
+            visitedDetail.Add(orgDetail);
         }
 
-        visitedDetail.Add(orgDetail);
+
+
         visitedDetail.Add(seatDetail);
 
         await _orderVisitDetailRepository.AddRangeAsync(visitedDetail, cancellationToken);
@@ -681,29 +701,29 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     /// <returns></returns>
     public async Task TriggerAverageOrder(CancellationToken cancellationToken)
     {
-		// 增加回收机制  先回收有未处理的工单 再进行平均派单
-		//1.从排班里面获取今天上班的人
-		//2.获取默认派单员剩下的工单
-		//3.平均分配剩下的工单给今天上班的人
-		#region 回收机制
-		DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
-		var roleId = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];
-
-		var schedulingUsers = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
-			.Where(x => x.SchedulingTime!.Value == time && (x.AtWork == null || x.AtWork == false) )
-            .Select(x=> new SchedulingUser { UserId = x.SchedulingUser.UserId } )
-			.ToListAsync(cancellationToken);
+        // 增加回收机制  先回收有未处理的工单 再进行平均派单
+        //1.从排班里面获取今天上班的人
+        //2.获取默认派单员剩下的工单
+        //3.平均分配剩下的工单给今天上班的人
+        #region 回收机制
+        DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
+        var roleId = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];
+
+        var schedulingUsers = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
+            .Where(x => x.SchedulingTime!.Value == time && (x.AtWork == null || x.AtWork == false))
+            .Select(x => new SchedulingUser { UserId = x.SchedulingUser.UserId })
+            .ToListAsync(cancellationToken);
         var userIds = schedulingUsers.Select(x => x.UserId).ToList();
-		var usersSteps = await _workflowDomainService.GetStepsBelongsDayToAsync(userIds, time, cancellationToken);
+        var usersSteps = await _workflowDomainService.GetStepsBelongsDayToAsync(userIds, time, cancellationToken);
         if (usersSteps != null && usersSteps.Any())
         {
-			await _workflowDomainService.ChangeHandlerBatchAsync(new List<(string userId, string username, string orgId, string orgName, string? roleId, string? roleName, ICollection<WorkflowStep> steps)>
-			{
-				new(AppDefaults.SendPoolId, "派单池", OrgSeedData.CenterId, OrgSeedData.CenterName,roleId,"派单员", usersSteps)
-			}, cancellationToken);
-		}
-		#endregion
-		var schedulings = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
+            await _workflowDomainService.ChangeHandlerBatchAsync(new List<(string userId, string username, string orgId, string orgName, string? roleId, string? roleName, ICollection<WorkflowStep> steps)>
+            {
+                new(AppDefaults.SendPoolId, "派单池", OrgSeedData.CenterId, OrgSeedData.CenterName,roleId,"派单员", usersSteps)
+            }, cancellationToken);
+        }
+        #endregion
+        var schedulings = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
             .Where(x => x.SchedulingTime!.Value == time && x.WorkingTime!.Value <= DateTime.Now.TimeOfDay && x.OffDutyTime!.Value >= DateTime.Now.TimeOfDay && x.AtWork == true)
             .OrderBy(x => x.SendOrderNum).ToListAsync(cancellationToken);
         if (schedulings.Any())
@@ -750,75 +770,75 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         }
     }
 
-	/// <summary>
-	/// 提前触发平均派单
-	/// </summary>
-	/// <param name="cancellationToken"></param>
-	/// <returns></returns>
-	public async Task AdvancedTriggerAverageOrder(CancellationToken cancellationToken) 
+    /// <summary>
+    /// 提前触发平均派单
+    /// </summary>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task AdvancedTriggerAverageOrder(CancellationToken cancellationToken)
     {
-		//1.从排班里面获取今天上班的人
-		//2.获取默认派单员剩下的工单
-		//3.平均分配剩下的工单给今天上班的人
-		DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
+        //1.从排班里面获取今天上班的人
+        //2.获取默认派单员剩下的工单
+        //3.平均分配剩下的工单给今天上班的人
+        DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
         DateTime fallsTime = DateTime.Parse("00:00:00");
-		var schedulings = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
-			.Where(x => x.SchedulingTime!.Value == time && x.WorkingTime!.Value != fallsTime.TimeOfDay && x.OffDutyTime!.Value != fallsTime.TimeOfDay )
-			.OrderBy(x => x.SendOrderNum).ToListAsync(cancellationToken);
-		var roleId = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];
-		if (schedulings.Any())
-		{
-			var steps = await _workflowDomainService.GetStepsBelongsToAsync(AppDefaults.SendPoolId,
-				cancellationToken);
-			if (steps.Any())
-			{
-				List<(string userId, string username, string orgId, string orgName, string? roleId, string? roleName, ICollection<WorkflowStep> steps)> handlers = new();
-				var avg = steps.Count / schedulings.Count;
-				var remaining = steps.Count % schedulings.Count;
-				var skip = 0;
-				for (var i = 0; i < schedulings.Count; i++)
-				{
-					var scheduling = schedulings[i];
-					var size = avg + (i < remaining ? 1 : 0);
-					if (size > 0)
-					{
-						var stSteps = steps.Skip(skip).Take(size).ToList();
-
-						handlers.Add(new(
-							scheduling.SchedulingUser.UserId,
-							scheduling.SchedulingUser.UserName,
-							scheduling.SchedulingUser.OrgId,
-							scheduling.SchedulingUser.OrgIdName,
-							roleId, "派单员",
-							stSteps));
-						skip += size;
-						scheduling.SendOrderNum = scheduling.SendOrderNum.HasValue ? scheduling.SendOrderNum.Value : 0; 
-						scheduling.SendOrderNum += size;
-						await _schedulingRepository.Updateable()
-							.SetColumns(s => new Scheduling() { SendOrderNum = scheduling.SendOrderNum, AdvancedSendOrderNum = size })
-							.Where(s => s.Id == scheduling.Id).ExecuteCommandAsync(cancellationToken);
-						await _orderRepository.Updateable().SetColumns(o => new Order()
-						{
-							CenterToOrgHandlerId = scheduling.SchedulingUser.UserId,
-							CenterToOrgHandlerName = scheduling.SchedulingUser.UserName
-						})
-							.Where(o => stSteps.Any(s => s.ExternalId == o.Id)).ExecuteCommandAsync(cancellationToken);
-					}
-				}
-				if (handlers.Any())
-					await _workflowDomainService.ChangeHandlerBatchAsync(handlers, cancellationToken);
-			}
-		}
-	}
-	#endregion
-
-	#region  工单校验- 交通类工单
-
-	/// <summary>
-	/// 工单校验  - 交通类工单
-	/// </summary>
-	/// <returns></returns>
-	public async Task<OrderValidation> OrderValidation(AddOrderDto dto, CancellationToken cancellationToken)
+        var schedulings = await _schedulingRepository.Queryable().Includes(x => x.SchedulingUser)
+            .Where(x => x.SchedulingTime!.Value == time && x.WorkingTime!.Value != fallsTime.TimeOfDay && x.OffDutyTime!.Value != fallsTime.TimeOfDay)
+            .OrderBy(x => x.SendOrderNum).ToListAsync(cancellationToken);
+        var roleId = _systemSettingCacheManager.GetSetting(SettingConstants.RolePaiDan)?.SettingValue[0];
+        if (schedulings.Any())
+        {
+            var steps = await _workflowDomainService.GetStepsBelongsToAsync(AppDefaults.SendPoolId,
+                cancellationToken);
+            if (steps.Any())
+            {
+                List<(string userId, string username, string orgId, string orgName, string? roleId, string? roleName, ICollection<WorkflowStep> steps)> handlers = new();
+                var avg = steps.Count / schedulings.Count;
+                var remaining = steps.Count % schedulings.Count;
+                var skip = 0;
+                for (var i = 0; i < schedulings.Count; i++)
+                {
+                    var scheduling = schedulings[i];
+                    var size = avg + (i < remaining ? 1 : 0);
+                    if (size > 0)
+                    {
+                        var stSteps = steps.Skip(skip).Take(size).ToList();
+
+                        handlers.Add(new(
+                            scheduling.SchedulingUser.UserId,
+                            scheduling.SchedulingUser.UserName,
+                            scheduling.SchedulingUser.OrgId,
+                            scheduling.SchedulingUser.OrgIdName,
+                            roleId, "派单员",
+                            stSteps));
+                        skip += size;
+                        scheduling.SendOrderNum = scheduling.SendOrderNum.HasValue ? scheduling.SendOrderNum.Value : 0;
+                        scheduling.SendOrderNum += size;
+                        await _schedulingRepository.Updateable()
+                            .SetColumns(s => new Scheduling() { SendOrderNum = scheduling.SendOrderNum, AdvancedSendOrderNum = size })
+                            .Where(s => s.Id == scheduling.Id).ExecuteCommandAsync(cancellationToken);
+                        await _orderRepository.Updateable().SetColumns(o => new Order()
+                        {
+                            CenterToOrgHandlerId = scheduling.SchedulingUser.UserId,
+                            CenterToOrgHandlerName = scheduling.SchedulingUser.UserName
+                        })
+                            .Where(o => stSteps.Any(s => s.ExternalId == o.Id)).ExecuteCommandAsync(cancellationToken);
+                    }
+                }
+                if (handlers.Any())
+                    await _workflowDomainService.ChangeHandlerBatchAsync(handlers, cancellationToken);
+            }
+        }
+    }
+    #endregion
+
+    #region  工单校验- 交通类工单
+
+    /// <summary>
+    /// 工单校验  - 交通类工单
+    /// </summary>
+    /// <returns></returns>
+    public async Task<OrderValidation> OrderValidation(AddOrderDto dto, CancellationToken cancellationToken)
     {
         var valid = new OrderValidation { Validation = false, Result = "" };
         var hotspot = await _hotspotRepository.GetAsync(dto.HotspotId, cancellationToken);
@@ -979,10 +999,40 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     }
     #endregion
 
+    /// <summary>
+    /// 查询中心最后一次会签的所有一级部门
+    /// </summary>
+    /// <param name="workFlowId"></param>
+    /// <returns></returns>
+    public async Task<List<Kv>> GetCountersignOneOrg(string workFlowId)
+    {
+        //查询最后一次派单组发起的会签
+        var sendStep = await _workflowTraceRepository.Queryable()
+               .Where(p => p.WorkflowId == workFlowId && p.BusinessType == EBusinessType.Send && p.Status == EWorkflowStepStatus.Handled
+               && p.IsStartCountersign == true && !string.IsNullOrEmpty(p.StartCountersignId) && p.ModuleCode == "OrderHandle")
+               .OrderByDescending(p => p.CreationTime)
+               .FirstAsync();
+        //查询当前会签下面已办理的所有一级部门
+        if (sendStep != null)
+        {
+            var orgList = await _workflowTraceRepository.Queryable()
+                  .Where(p => p.WorkflowId == workFlowId //&& p.CountersignPosition == ECountersignPosition.Direct
+                  && p.CountersignId == sendStep.StartCountersignId //&& p.IsStartCountersign == false
+                  && p.BusinessType == EBusinessType.Department && p.HandlerOrgId.Length == 6)
+                  .Select(p => new Kv
+                  {
+                      Key = p.HandlerOrgId,
+                      Value = p.HandlerOrgName
+                  })
+                  .ToListAsync();
+            return orgList;
+        }
+        return new List<Kv>();
+    }
 
-	#region private
+    #region private
 
-	private async Task<Order> GetOrderByFlowIdAsync(string workflowId, CancellationToken cancellationToken)
+    private async Task<Order> GetOrderByFlowIdAsync(string workflowId, CancellationToken cancellationToken)
     {
         if (string.IsNullOrEmpty(workflowId))
             throw UserFriendlyException.SameMessage("无效流程编号");

+ 67 - 18
test/Hotline.Tests/Controller/OrderDelayControllerTest.cs

@@ -1,6 +1,7 @@
 using Hotline.Tests.Mock;
 using System.Diagnostics;
 using Hotline.Api.Controllers;
+using Hotline.Api.Controllers.OrderApi;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Settings;
@@ -15,16 +16,19 @@ using Hotline.Orders;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.FlowEngine.Workflow;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.Order.OrderDelay;
 using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using MapsterMapper;
 using Xunit.Abstractions;
+using Microsoft.AspNetCore.Mvc;
 
 namespace Hotline.Tests.Controller
 {
     public class OrderDelayControllerTest : TestBase
     {
         private readonly OrderController _orderController;
+        private readonly OrderDelayController _orderDelayController;
         private readonly OrderServiceMock _orderServiceMock;
         private readonly IOrderDelayRepository _orderDelayRepository;
         private readonly IOrderRepository _orderRepository;
@@ -37,6 +41,7 @@ namespace Hotline.Tests.Controller
             IThirdAccountRepository thirdAccountRepository, ITypedCache<SystemSetting> cacheSettingData,
             ThirdAccounSupplierFactory thirdAccountDomainFactory,
             OrderController orderController,
+            OrderDelayController orderDelayController,
             OrderServiceMock orderServiceMock,
             IOrderDelayRepository orderDelayRepository,
             IOrderRepository orderRepository,
@@ -46,57 +51,101 @@ namespace Hotline.Tests.Controller
             thirdAccountRepository, cacheSettingData, thirdAccountDomainFactory, serviceProvider)
         {
             _orderController = orderController;
+            _orderDelayController = orderDelayController;
             _orderServiceMock = orderServiceMock;
             _orderDelayRepository = orderDelayRepository;
             _orderRepository = orderRepository;
             _mapper = mapper;
             _testOutputHelper = testOutputHelper;
+
+            _orderController.ControllerContext = new ControllerContext
+            {
+                HttpContext = new DefaultHttpContext
+                {
+                    RequestAborted = CancellationToken.None
+                }
+            };
+            _orderDelayController.ControllerContext = new ControllerContext
+            {
+                HttpContext = new DefaultHttpContext
+                {
+                    RequestAborted = CancellationToken.None
+                }
+            };
         }
 
         [Fact]
-        public async Task OrderDelayBatchApproveTest()
+        public async Task OrderDelayBatchReviewTest()
         {
             SetZuoXi();
 
             var delayIds = new List<string>();
-            for (int i = 0; i < 10; i++)
+            for (int i = 0; i < 6; i++)
             {
-                var orderId = _orderServiceMock.CreateOrder()
+                var order = _orderServiceMock.CreateOrder()
                     .办理到一级部门()
-                    .办理到二级部门(Set一级部门)
-                    .GetCreateResult().Id;
+                    //.办理到二级部门(Set一级部门)
+                    //.办理一级部门汇总(Set二级部门)
+                    //.办理到归档(Set一级部门)
+                    //.发布工单(SetZuoXi)
+                    .GetCreateResult();
 
                 //var order = await _orderRepository.Queryable()
                 //    .FirstAsync(o => o.Id == orderId);
-                var delayId = _orderServiceMock.申请延期(Set级部门);
+                var delayId = _orderServiceMock.申请延期(Set级部门);
                 delayIds.Add(delayId);
             }
 
-            var delay = await _orderDelayRepository.GetAsync(delayIds.First());
-            
-            Set一级部门();
-            var option =  _orderController.OrderDelayNextsteps(delay.WorkflowId).Result as NextStepsWithOpinionDto<NextStepOption>;
-            var step = option.Steps.First();
-            
-            var req = new BatchDelayNextFlowDto
+            Set班长();
+            var delays = await _orderDelayController.QueryWaited(new DelayListDto
+            {
+                IsApply = false,
+            });
+
+            var delayWithIds = delays
+                .Where(d => delayIds.Contains(d.Id))
+                .Select(d => new DelayWithStepId
+                {
+                    DelayId = d.Id,
+                    StepId = d.StepId,
+                    WorkflowId = d.WorkflowId
+                }).ToList();
+
+            var delay = delays.First();
+
+            var option = _orderController.OrderDelayNextsteps(delay.WorkflowId).Result as NextStepsWithOpinionDto<NextStepOption>;
+            var step = option.Steps.First(d=>d.StepType == EStepType.End);
+
+            //var req = new BatchDelayNextFlowDto
+            //{
+            //    DelayId = delayIds.ToArray(),
+            //    IsPass = true,
+            //    NextWorkflow = new NextWorkflowDto
+            //    {
+            //        NextStepCode = step.Key,
+            //        NextStepName = step.Value,
+            //    }
+            //};
+
+            var req = new BatchOrderDelayReviewRequest
             {
-                DelayId = delayIds.ToArray(),
                 IsPass = true,
+                DelayWithStepIds = delayWithIds,
                 NextWorkflow = new NextWorkflowDto
                 {
                     NextStepCode = step.Key,
-                    NextStepName = step.Value,
+                    NextStepName = step.Value
                 }
             };
 
             _testOutputHelper.WriteLine($"开始审批");
             var sw = new Stopwatch();
             sw.Start();
-            var result = await _orderController.BatchAuditDelay(req);
+            await _orderDelayController.BatchReview(req);
             sw.Stop();
-            
+
             _testOutputHelper.WriteLine($"耗时:{sw.ElapsedMilliseconds}ms");
-            _testOutputHelper.WriteLine(result);
+
 
             //var delay = await _orderDelayRepository.Queryable()
             //    .Includes(d => d.Order)

+ 1 - 1
test/Hotline.Tests/Mock/OrderServiceMock.cs

@@ -684,7 +684,7 @@ public class OrderServiceMock
             {
                 NextStepCode = step.Key,
                 NextStepName = step.Value,
-                NextHandlers = new List<StepAssignInfo> { step.Items.First() },
+                NextHandlers = new List<StepAssignInfo> { /*step.Items.First()*/ },
                 Opinion = "单元测试延期申请",
                 FlowDirection = step.FlowDirection,
                 BackToCountersignEnd = step.BackToCountersignEnd,

+ 2 - 0
test/Hotline.Tests/Startup.cs

@@ -2,6 +2,7 @@
 using DotNetCore.CAP;
 using Hotline.Api;
 using Hotline.Api.Controllers;
+using Hotline.Api.Controllers.OrderApi;
 using Hotline.Api.Controllers.Snapshot;
 using Hotline.Application;
 using Hotline.Application.CallCenter;
@@ -169,6 +170,7 @@ public class Startup
             services.AddScoped<IMediator, MediatorMock>();
             services.AddScoped<IExportApplication, ExportApplication>();
             services.AddScoped<OrderController>();
+            services.AddScoped<OrderDelayController>();
             services.AddScoped<IndustryController>();
             services.AddScoped<UserController>();
             services.AddScoped<SnapshotController>();