Browse Source

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

libin 3 weeks ago
parent
commit
cd2746da10
31 changed files with 296 additions and 143 deletions
  1. 20 19
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  2. 131 74
      src/Hotline.Api/Controllers/OrderController.cs
  3. 6 1
      src/Hotline.Api/Controllers/TestController.cs
  4. 1 12
      src/Hotline.Application/CallCenter/DefaultCallApplication.cs
  5. 5 1
      src/Hotline.Application/OrderApp/Handlers/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs
  6. 3 2
      src/Hotline.Application/OrderApp/OrderApplication.cs
  7. 0 1
      src/Hotline.Application/Snapshot/Contracts/IOrderSnapshotApplication.cs
  8. 2 0
      src/Hotline.Application/Snapshot/IndustryApplication.cs
  9. 10 1
      src/Hotline.Application/Snapshot/RedPackApplication.cs
  10. 9 8
      src/Hotline.Application/Snapshot/SnapshotOrderApplication.cs
  11. 1 1
      src/Hotline.Repository.SqlSugar/System/SystemLogRepository.cs
  12. 5 0
      src/Hotline.Share/Dtos/CallCenter/QueryCallsFixedDto.cs
  13. 4 0
      src/Hotline.Share/Dtos/Order/Detail/OrderFlowTraceDto.cs
  14. 5 0
      src/Hotline.Share/Dtos/Order/OrderDto.cs
  15. 21 1
      src/Hotline.Share/Dtos/Snapshot/OrderDto.cs
  16. 2 0
      src/Hotline.Share/Dtos/Snapshot/RedPackDto.cs
  17. 6 1
      src/Hotline.Share/Enums/FlowEngine/EFlowDirection.cs
  18. 6 0
      src/Hotline.Share/Enums/FlowEngine/EHandleMode.cs
  19. 6 0
      src/Hotline.Share/Enums/FlowEngine/EWorkflowTraceType.cs
  20. 1 1
      src/Hotline.Share/Tools/EnumExtensions.cs
  21. 1 1
      src/Hotline/FlowEngine/WorkflowModules/WorkflowModuleConsts.cs
  22. 11 9
      src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs
  23. 1 1
      src/Hotline/Identity/IdentityDomainService.cs
  24. 1 0
      src/Hotline/Orders/OrderVisitDetail.cs
  25. 4 4
      src/Hotline/SeedData/SystemDicDataSeedData.cs
  26. 1 1
      src/Hotline/Snapshot/Contracts/ISnapshotPointsDomainService.cs
  27. 6 0
      src/Hotline/Snapshot/Industry.cs
  28. 2 1
      src/Hotline/Snapshot/Services/SnapshotPointsDomainService.cs
  29. 2 0
      test/Hotline.Tests/Application/IndustryApplicationTest.cs
  30. 21 1
      test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs
  31. 2 2
      test/Hotline.Tests/Mock/OrderServiceMock.cs

+ 20 - 19
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -2364,24 +2364,25 @@ namespace Hotline.Api.Controllers.Bi
              .Where(x => x.VisitTime >= StartTime && x.VisitTime <= EndTime && x.VisitState != EVisitState.None && x.VisitState != EVisitState.Visited).CountAsync()
             };
             //
-            var data = await _orderVisitDetailRepository.Queryable()
+            var query = _orderVisitDetailRepository.Queryable()
                 .LeftJoin<OrderVisit>((it, o) => it.VisitId == o.Id)
                 .LeftJoin<SystemOrganize>((it, o, so) => it.VisitOrgCode == so.Id)
                 .Where((it, o, so) => it.VisitTarget == EVisitTarget.Org && o.VisitTime >= StartTime && o.VisitTime <= EndTime && o.VisitState == EVisitState.Visited)
                  .Select((it, o, so) => new
                  {
-                     Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
-                     Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 0, 1)),
-                     CityDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.OrgType == EOrgType.City, 1, 0)),
-                     CitySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.OrgType == EOrgType.City, 1, 0)),
-                     CountyDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.OrgType == EOrgType.County, 1, 0)),
-                     CountySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.OrgType == EOrgType.County, 1, 0)),
-                     CenterDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.IsCenter, 1, 0)),
-                     CenterSatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.IsCenter, 1, 0)),
-                     OrgDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && !so.IsCenter, 1, 0)),
-                     OrgSatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && !so.IsCenter, 1, 0)),
-                 })
-                .FirstAsync();
+                     Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2", 1, 0)),
+                     Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "2", 0, 1)),
+                     CityDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "2") && so.OrgType == EOrgType.City, 1, 0)),
+                     CitySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "2") && so.OrgType == EOrgType.City, 1, 0)),
+                     CountyDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2") && so.OrgType == EOrgType.County, 1, 0)),
+                     CountySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2") && so.OrgType == EOrgType.County, 1, 0)),
+                     CenterDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2") && so.IsCenter, 1, 0)),
+                     CenterSatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "2") && so.IsCenter, 1, 0)),
+                     OrgDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2") && !so.IsCenter, 1, 0)),
+                     OrgSatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "2") && !so.IsCenter, 1, 0)),
+                 });
+            Console.Write(query.ToSqlString());
+             var data = await query.FirstAsync();
             if (data.Satisfied > 0)
             {
                 var count = data.Satisfied + data.Dissatisfied;
@@ -2659,12 +2660,12 @@ namespace Hotline.Api.Controllers.Bi
                 .Select((it, so) => new EnterpriseOrderDto
                 {
                     VisitdCount = SqlFunc.AggregateCount(1),
-                    Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
-                    Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2"), 1, 0)),
-                    CityDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.OrgType == EOrgType.City, 1, 0)),
-                    CitySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.OrgType == EOrgType.City, 1, 0)),
-                    CountyDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") || SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2")) && so.OrgType == EOrgType.County, 1, 0)),
-                    CountySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "1") && !SqlFunc.JsonListObjectAny(it.OrgProcessingResults, "key", "2") && so.OrgType == EOrgType.County, 1, 0)),
+                    Dissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2", 1, 0)),
+                    Satisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2"), 1, 0)),
+                    CityDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="2") && so.OrgType == EOrgType.City, 1, 0)),
+                    CitySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "2") && so.OrgType == EOrgType.City, 1, 0)),
+                    CountyDissatisfied = SqlFunc.AggregateSum(SqlFunc.IIF((SqlFunc.JsonField(it.OrgProcessingResults, "Key")=="1" || SqlFunc.JsonField(it.OrgProcessingResults, "Key")== "2") && so.OrgType == EOrgType.County, 1, 0)),
+                    CountySatisfied = SqlFunc.AggregateSum(SqlFunc.IIF(!(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "1") && !(SqlFunc.JsonField(it.OrgProcessingResults, "Key") == "2") && so.OrgType == EOrgType.County, 1, 0)),
                 })
                 .ToListAsync();
 

+ 131 - 74
src/Hotline.Api/Controllers/OrderController.cs

@@ -53,6 +53,7 @@ using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Push;
 using Hotline.Share.Enums.Settings;
+using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Mq;
 using Hotline.Share.Requests;
 using Hotline.Share.Tools;
@@ -70,6 +71,7 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using MiniExcelLibs;
 using SqlSugar;
+using System.Diagnostics;
 using System.Text;
 using System.Text.Json;
 using System.Threading;
@@ -90,6 +92,7 @@ public class OrderController : BaseController
 {
     #region 注入
 
+    private readonly ISystemLogRepository _systemLogRepository;
     private readonly IOrderDomainService _orderDomainService;
     private readonly BaseDataApplication _baseDataApplication;
     private readonly IOrderRepository _orderRepository;
@@ -165,6 +168,7 @@ public class OrderController : BaseController
     private readonly ICircularRecordDomainService _circularRecordDomainService;
     private readonly IRepository<Hotline.Special.SpecialNumber> _specialNumberRepository;
     private readonly IRepository<OrderVisitDetailCopy> _orderVisitDetailCopyRepository;
+    private readonly IRedPackAuditRepository _redPackAuditRepository;
 
     public OrderController(
         IOrderDomainService orderDomainService,
@@ -241,8 +245,10 @@ public class OrderController : BaseController
         IRepository<SystemOrganize> systemOrganizeRepository,
         IRepository<OrderComplement> orderComplementRepository,
         ICircularRecordDomainService circularRecordDomainService,
+        IRedPackAuditRepository redPackAuditRepository,
         IRepository<Hotline.Special.SpecialNumber> specialNumberRepository,
-        IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository)
+        IRepository<OrderVisitDetailCopy> orderVisitDetailCopyRepository,
+        ISystemLogRepository systemLogRepository)
     {
         _orderDomainService = orderDomainService;
         _orderRepository = orderRepository;
@@ -318,8 +324,10 @@ public class OrderController : BaseController
         _systemOrganizeRepository = systemOrganizeRepository;
         _orderComplementRepository = orderComplementRepository;
         _circularRecordDomainService = circularRecordDomainService;
+        _redPackAuditRepository = redPackAuditRepository;
         _specialNumberRepository = specialNumberRepository;
         _orderVisitDetailCopyRepository = orderVisitDetailCopyRepository;
+        _systemLogRepository = systemLogRepository;
     }
 
     #endregion
@@ -4045,7 +4053,7 @@ public class OrderController : BaseController
             .Includes(d => d.OrderScreens)
             .Includes(d => d.OrderTerminates)
             .Where(d => d.Contact == dto.PhoneNo)
-            .WhereIF(_sessionContext.OrgIsCenter == false && (_appOptions.Value.IsYiBin == true  || _appOptions.Value.IsLuZhou == true ), d => d.IsSecret == false)
+            .WhereIF(_sessionContext.OrgIsCenter == false && (_appOptions.Value.IsYiBin == true || _appOptions.Value.IsLuZhou == true), d => d.IsSecret == false)
             .WhereIF(!string.IsNullOrEmpty(dto.OrderId) && _appOptions.Value.IsLuZhou == false, d => d.Id != dto.OrderId)
             .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword!) || d.No.Contains(dto.Keyword!))
             .Select(d => new OrderHistoryOutDto
@@ -4332,14 +4340,21 @@ public class OrderController : BaseController
             List<OrderRemarksDto> remarks = workflow.Steps.Where(x => !string.IsNullOrEmpty(x.Remark)).Select(x => new OrderRemarksDto
             { Remark = x.Remark, RemarkTime = x.HandleTime, RemarkUser = x.HandlerName }).ToList();
             dto.OrderRemarks = remarks;
+            //退回
             if (order.Status == EOrderStatus.SendBack || order.Status == EOrderStatus.BackToUnAccept)
             {
                 var backTrace = workflow.Traces.Where(x => x.Status == EWorkflowStepStatus.Handled).OrderByDescending(x => x.CreationTime).First();
-                backTrace.Opinion = backTrace.Opinion.Replace("流程归档", "");
-                dto.SendBackOpinion = string.IsNullOrEmpty(backTrace.Opinion) ? string.Empty : backTrace.HandlerOrgName + "   " + backTrace.Opinion;
+                // backTrace.Opinion = backTrace.Opinion.Replace("流程归档", "");
+                dto.SendBackOpinion = string.IsNullOrEmpty(backTrace.Opinion) ? string.Empty : "【" + backTrace.HandlerOrgName + "】" + backTrace.Opinion;
                 //var sendBack = await _orderSendBackAuditRepository.Queryable().Where(x => x.OrderId == dto.Id).OrderByDescending(x => x.CreationTime).FirstAsync();
                 //dto.SendBackOpinion = sendBack is { Id: not null } && !string.IsNullOrEmpty(sendBack.Content) ? sendBack.Content : string.Empty;
             }
+            //重办
+            if (order.Status == EOrderStatus.Special || order.Status == EOrderStatus.SpecialToUnAccept)
+            {
+                var reTransactTrace = workflow.Traces.Where(x => x.Status == EWorkflowStepStatus.Handled).OrderByDescending(x => x.CreationTime).First();
+                dto.ReTransactOpinion = string.IsNullOrEmpty(reTransactTrace.Opinion) ? string.Empty : "【" + reTransactTrace.HandlerOrgName + "】" + reTransactTrace.Opinion;
+            }
         }
 
         //工单是否在退回审批中
@@ -4548,13 +4563,13 @@ public class OrderController : BaseController
         }
         if (_appOptions.Value.IsLuZhou)
         {
-			//期满时间
-			var expiredTimeConfig =
-			   await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter, order.Adapt<OrderTimeClacInfo>());
-			_mapper.Map(expiredTimeConfig, order);
-		}
+            //期满时间
+            var expiredTimeConfig =
+               await _expireTime.CalcExpiredTime(DateTime.Now, DateTime.Now, EFlowDirection.CenterToCenter, order.Adapt<OrderTimeClacInfo>());
+            _mapper.Map(expiredTimeConfig, order);
+        }
 
-		await _orderDomainService.AddAsync(order, true, HttpContext.RequestAborted);
+        await _orderDomainService.AddAsync(order, true, HttpContext.RequestAborted);
 
         if (_systemSettingCacheManager.Snapshot && dto.IndustryId.NotNullOrEmpty() && dto.IndustryName.NotNullOrEmpty())
         {
@@ -4978,7 +4993,7 @@ public class OrderController : BaseController
         try
         {
             var startDto = _mapper.Map<StartWorkflowDto>(dto.Workflow);
-            startDto.DefinitionModuleCode = WorkflowModuleConsts.OrderHandle;
+            startDto.DefinitionModuleCode = await _orderSnapshotApplication.GetStartflowAsync(order.Id, HttpContext.RequestAborted);
             startDto.Title = order.Title;
             var (workflow, startStep) =
                 await _workflowDomainService.StartAsync(startDto, order.Id, order.ExpiredTime, cancellationToken: HttpContext.RequestAborted);
@@ -5002,12 +5017,12 @@ public class OrderController : BaseController
     /// <summary>
     /// 查询工单办理流程开启参数
     /// </summary>
-    /// <returns></returns>4
+    /// <returns></returns>
     [HttpGet("startflow")]
     public async Task<NextStepsDto> GetFlowStartOptions([FromQuery] string? orderId)
     {
-        var dto = await _workflowApplication.GetStartStepsAsync(await _orderSnapshotApplication.GetStartflowAsync(orderId, HttpContext.RequestAborted),
-            HttpContext.RequestAborted);
+        var modelCode = await _orderSnapshotApplication.GetStartflowAsync(orderId, HttpContext.RequestAborted);
+        var dto = await _workflowApplication.GetStartStepsAsync(modelCode, HttpContext.RequestAborted);
         if (orderId.NotNullOrEmpty())
         {
             dto.Opinion = await _typeCache.GetAsync($"tmp_opinion_{orderId}{_sessionContext.UserId}", HttpContext.RequestAborted);
@@ -5109,10 +5124,8 @@ public class OrderController : BaseController
         var order = await _orderApplication.SaveOrderWorkflowInfo(dto, HttpContext.RequestAborted);
 
         // 随手拍业务处理
-        if (_systemSettingCacheManager.Snapshot)
-        {
-            await _orderSnapshotApplication.SaveOrderWorkflowInfo(dto);
-        }
+        await _orderSnapshotApplication.SaveOrderWorkflowInfo(dto);
+        
         //await _workflowApplication.NextAsync(dto.WorkflowDto, order.ExpiredTime, HttpContext.RequestAborted);
         var startStep = workflow.Steps.First(d => d.Id == dto.Workflow.StepId);
         await HandleOrderAsync(order, workflow, startStep, dto.Data, dto.Workflow, HttpContext.RequestAborted);
@@ -5137,69 +5150,91 @@ public class OrderController : BaseController
     public async Task<string> OrderSignBathAsync([FromBody] OrderSignBathInDto dto)
     {
         var stringBuilder = new StringBuilder();
-        foreach (var orderId in dto.OrderIds)
+        if (dto.Status == 1)
         {
-            var order = await _orderRepository.GetAsync(orderId, HttpContext.RequestAborted);
-            if (order is null)
+            foreach (var orderId in dto.OrderIds)
             {
-                continue;
-            }
+                var order = await _orderRepository.GetAsync(orderId, HttpContext.RequestAborted);
+                if (order is null)
+                {
+                    continue;
+                }
 
-            var snapshot = await _orderSnapshotApplication.UpdateSafetyAsync(orderId, dto.IsSafetyDepartment, dto.Remark);
-            if (snapshot is null)
-            {
-                stringBuilder.Append($"随手拍: {order.No} 不存在");
-                continue;
-            }
+                var snapshot = await _orderSnapshotApplication.UpdateSafetyAsync(orderId, dto.IsSafetyDepartment, dto.Remark);
+                if (snapshot is null)
+                {
+                    stringBuilder.Append($"随手拍: {order.No} 不存在");
+                    continue;
+                }
 
-            var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withDefine: true, withSteps: true, withTraces: true,
-                cancellationToken: HttpContext.RequestAborted);
+                var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withDefine: true, withSteps: true, withTraces: true,
+                    cancellationToken: HttpContext.RequestAborted);
 
-            NextStepsWithOpinionDto<NextStepOption> nextSteps;
-            try
-            {
-                nextSteps = await _workflowApplication.GetNextStepsAsync(order.WorkflowId, HttpContext.RequestAborted);
-            }
-            catch (UserFriendlyException e)
-            {
-                if (e.Message.Contains("未找到对应节点"))
+                NextStepsWithOpinionDto<NextStepOption> nextSteps;
+                try
+                {
+                    nextSteps = await _workflowApplication.GetNextStepsAsync(order.WorkflowId, HttpContext.RequestAborted);
+                }
+                catch (UserFriendlyException e)
+                {
+                    if (e.Message.Contains("未找到对应节点"))
+                    {
+                        stringBuilder.AppendLine($"{order.No} " + e.Message);
+                        continue;
+                    }
+
+                    throw;
+                }
+
+                var stepInfo = nextSteps.Steps.FirstOrDefault(m => m.BusinessType == EBusinessType.Send);
+                if (stepInfo == null)
                 {
-                    stringBuilder.AppendLine($"{order.No} 修改成功");
+                    stringBuilder.Append($"下一步节点: [派单组] 未找到");
                     continue;
                 }
 
-                throw;
+                var data = new OrderHandleFlowDto
+                {
+                    OrderId = orderId,
+                    IsSafetyDepartment = dto.IsSafetyDepartment
+                };
+                var workflowDto = new NextWorkflowDto
+                {
+                    WorkflowId = order.WorkflowId,
+                    StepId = nextSteps.StepId,
+                    NextStepCode = stepInfo.Key,
+                    NextStepName = stepInfo.Value,
+                    Opinion = dto.Remark,
+                    BackToCountersignEnd = false,
+                    IsSms = false,
+                    IsForwarded = false,
+                    HandlerType = EHandlerType.OrgLevel,
+                    BusinessType = EBusinessType.Send,
+                    FlowDirection = EFlowDirection.CenterToCenter,
+                };
+                var startStep = workflow.Steps.First(d => d.Id == nextSteps.StepId);
+                await HandleOrderAsync(order, workflow, startStep, data, workflowDto, HttpContext.RequestAborted);
+                stringBuilder.AppendLine($"{orderId} 标注完成;");
             }
-
-            var stepInfo = nextSteps.Steps.FirstOrDefault(m => m.BusinessType == EBusinessType.Send);
-            if (stepInfo == null)
+        }
+        else
+        {
+            var orderNo = await _redPackAuditRepository.Queryable()
+                .LeftJoin<Order>((m, order) => m.OrderId == order.Id)
+                .Where(m => dto.OrderIds.Contains(m.OrderId) && m.Status != ERedPackAuditStatus.Pending)
+                .Select((m, order) => order.No)
+                .ToListAsync();
+            if (orderNo.NotNullOrEmpty())
+                throw new UserFriendlyException("该工单已红包审批,无法修改标记状态!");
+            else
             {
-                stringBuilder.Append($"下一步节点: [派单组] 未找到");
-                continue;
+                await _orderSnapshotRepository.Updateable()
+                    .SetColumns(m => m.IsSafetyDepartment, dto.IsSafetyDepartment)
+                    .SetColumns(m => m.SignRemark, dto.Remark)
+                    .Where(m => dto.OrderIds.Contains(m.Id))
+                    .ExecuteCommandAsync();
+                stringBuilder.AppendLine("标注完成;");
             }
-
-            var data = new OrderHandleFlowDto
-            {
-                OrderId = orderId,
-                IsSafetyDepartment = dto.IsSafetyDepartment
-            };
-            var workflowDto = new NextWorkflowDto
-            {
-                WorkflowId = order.WorkflowId,
-                StepId = nextSteps.StepId,
-                NextStepCode = stepInfo.Key,
-                NextStepName = stepInfo.Value,
-                Opinion = dto.Remark,
-                BackToCountersignEnd = false,
-                IsSms = false,
-                IsForwarded = false,
-                HandlerType = EHandlerType.OrgLevel,
-                BusinessType = EBusinessType.Send,
-                FlowDirection = EFlowDirection.CenterToCenter,
-            };
-            var startStep = workflow.Steps.First(d => d.Id == nextSteps.StepId);
-            await HandleOrderAsync(order, workflow, startStep, data, workflowDto, HttpContext.RequestAborted);
-            stringBuilder.AppendLine($"{orderId} 标注完成;");
         }
 
         return stringBuilder.ToString();
@@ -5366,7 +5401,7 @@ public class OrderController : BaseController
     {
         return (_, _, stepDefine, newStep) =>
         {
-            if (stepDefine.BusinessType is EBusinessType.Department or EBusinessType.DepartmentLeader)
+            if (stepDefine.BusinessType is EBusinessType.Department)
             {
                 newStep.HandlerId = null;
                 newStep.HandlerName = null;
@@ -5780,8 +5815,17 @@ public class OrderController : BaseController
             .Where(d => d.WorkflowId == workflowId && (d.HandleMode != EHandleMode.PreviousNoDisplay || d.HandleMode == null))
             .OrderBy(d => d.CreationTime)
             .ToTreeAsync(d => d.Traces, d => d.ParentId, null);
+        var data = _mapper.Map<List<OrderFlowTraceDto>>(traces);
+        foreach (var item in data)
+        {
+            if (item.TraceStyle == ETraceStyle.Publish && item.PublishState.HasValue)
+                item.OpinionResult = item.PublishState == true ? "公开" : "不公开";
 
-        return _mapper.Map<IReadOnlyList<OrderFlowTraceDto>>(traces);
+            if (item.TraceStyle == ETraceStyle.Visit && item.OrderFlowVisitDetails != null && item.OrderFlowVisitDetails.Any())
+                item.OpinionResult = string.Join(",", item.OrderFlowVisitDetails.Select(x => x.OrgProcessingResults));
+        }
+
+        return data;
     }
 
     /// <summary>
@@ -7023,11 +7067,24 @@ public class OrderController : BaseController
             //             { CenterToOrgHandlerId = flowStepHandler.UserId, CenterToOrgHandlerName = flowStepHandler.Username })
             //         .Where(o => o.Id == order.Id).ExecuteCommandAsync(HttpContext.RequestAborted);
             // }
+            var handleMode = EHandleMode.Redo;
+            var workflowTraceType = EWorkflowTraceType.Redo;
+            if (dto.SpecialType == ESpecialType.Special)
+            {
+                handleMode = EHandleMode.Recall;
+                workflowTraceType = EWorkflowTraceType.Recall;
+            }
+            if (dto.SpecialType == ESpecialType.SendBack)
+            {
+                handleMode = EHandleMode.PublishPrevious;
+                workflowTraceType = EWorkflowTraceType.PublishPrevious;
+            }
+
             DateTime endTime = order.ExpiredTime!.Value;
             var (workflow, targetStepDefine, currentStep, targetStep, newStep, isOrgToCenter) =
                 await _workflowDomainService.RecallAsync(
-                    recall, recall.NextHandlers.FirstOrDefault(), EWorkflowTraceType.Redo,
-                    endTime, order.Status >= EOrderStatus.Filed, EHandleMode.Redo,
+                    recall, recall.NextHandlers.FirstOrDefault(), workflowTraceType,
+                    endTime, order.Status >= EOrderStatus.Filed, handleMode,
                     (workflow, currentStep, targetStepDefine, targetStep, targetStepNew) =>
                     {
                         var stepAssignInfo = recall.NextHandlers.FirstOrDefault()
@@ -7647,7 +7704,7 @@ public class OrderController : BaseController
             }
         }
 
-        if (_appOptions.Value.IsYiBin && _appOptions.Value.IsLuZhou)
+        if (_appOptions.Value.IsYiBin || _appOptions.Value.IsLuZhou)
         {
             if (order.FileOrgIsCenter.Value)
             {

+ 6 - 1
src/Hotline.Api/Controllers/TestController.cs

@@ -1506,7 +1506,7 @@ public class TestController : BaseController
     public async Task OrderPushTypeCode([FromBody] OrderPushTypeCodeDto dto)
     {
         var orders = await _orderRepository.Queryable()
-            .Where(d => d.PushTypeCode.Contains(dto.PushTypeCode))
+            .Where(d => d.PushTypeCode.Contains(dto.PushTypeCode) && d.Source == ESource.Hotline)
             .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime) //受理时间开始
             .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime) //受理时间结束
             .ToListAsync(HttpContext.RequestAborted);
@@ -1537,5 +1537,10 @@ public class TestController : BaseController
 
         return ipv4;
     }
+
+    public string DecryptSign(string sign)
+    {
+        return sign;
+    }
 }
 

+ 1 - 12
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -341,6 +341,7 @@ public abstract class DefaultCallApplication : ICallApplication
             .WhereIF(!string.IsNullOrEmpty(dto.ToNo), d => d.ToNo.Contains(dto.ToNo!))
             .WhereIF(!string.IsNullOrEmpty(dto.UserName), d => d.UserName == dto.UserName)
             .WhereIF(!string.IsNullOrEmpty(dto.TelNo), d => d.TelNo == dto.TelNo)
+            .WhereIF(!string.IsNullOrEmpty(dto.CallNo), d => d.CallNo.Contains(dto.CallNo))
             .WhereIF(dto.EndBy != null, d => d.EndBy == dto.EndBy)
             .WhereIF(dto.CallStartTimeStart != null, d => d.BeginIvrTime >= dto.CallStartTimeStart)
             .WhereIF(dto.CallStartTimeEnd != null, d => d.BeginIvrTime <= dto.CallStartTimeEnd)
@@ -381,18 +382,6 @@ public abstract class DefaultCallApplication : ICallApplication
                 Title = o.Title,
                 IsVisit = !SqlFunc.IsNullOrEmpty(v.Id),
                 IsOrder = !SqlFunc.IsNullOrEmpty(o.Id),
-                StaffNo = SqlFunc.Coalesce(
-                    SqlFunc.IIF(d.StaffNo == "0", null, d.StaffNo),
-                    SqlFunc.Subqueryable<CallNative>()
-                        .Where(m => m.CallNo == d.CallNo && m.StaffNo != "0")
-                        .Max(m => m.StaffNo)
-                    ),
-                TelNo = SqlFunc.Coalesce(
-                    SqlFunc.IIF(d.TelNo == "0", null, d.TelNo),
-                    SqlFunc.Subqueryable<CallNative>()
-                        .Where(m => m.CallNo == d.CallNo && m.TelNo != "0")
-                        .Max(m => m.TelNo)
-                    ),
             }, true)
                 .WhereIF(!string.IsNullOrEmpty(dto.StaffNo), d => d.StaffNo == dto.StaffNo);
         }

+ 5 - 1
src/Hotline.Application/OrderApp/Handlers/OrderScreenHandler/OrderScreenEndWorkflowHandler.cs

@@ -84,7 +84,11 @@ public class OrderScreenEndWorkflowHandler : INotificationHandler<EndWorkflowNot
                         if (screen.ScreenType == EOrderScreenType.Seat)
                         {
                             visitDetail.SeatEvaluate = ESeatEvaluate.DefaultSatisfied;
-                            await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
+                            if (_appOptions.Value.IsZiGong)
+                            {
+								visitDetail.VoiceEvaluate = EVoiceEvaluate.DefaultSatisfied;
+							}
+							await _orderVisitedDetailRepository.UpdateAsync(visitDetail, cancellationToken);
                         }
                         else
                         {

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

@@ -4600,7 +4600,7 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         if (order == null)
         {
             order = _mapper.Map<Order>(dto);
-            if (order.IsSecret == true)
+            if (order.IsSecret == true && _appOptions.Value.IsYiBin == false)
             {
                 order.FocusOnEventsName = "保密";
                 order.FocusOnEvents = "99";
@@ -5571,7 +5571,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
                 //如果查询全部
                 //1.1、热线中心用户看系统中所有已申请延期的工单(需排除取消延期的工单)和自动延期的工单
                 //1.2、部门用户看部门及其下级部门已申请延期的工单(需排除取消延期的工单)和部门办理中时自动延期的工单
-                .WhereIF(dto.DataScope is 0, d => (d.AutomaticDelayNum == 0 || d.AutomaticDelayNum == null) && d.DelayState != EDelayState.Withdraw)
+                // .WhereIF(dto.DataScope is 0, d => (d.AutomaticDelayNum == 0 || d.AutomaticDelayNum == null) && d.DelayState != EDelayState.Withdraw)
+                .WhereIF(dto.DataScope is 0, d => d.DelayState != EDelayState.Withdraw)
                 .WhereIF(dto.DataScope is 0 && !_sessionContext.OrgIsCenter, d => d.CreatorOrgId.StartsWith(_sessionContext.RequiredOrgId))
                 .WhereIF(!string.IsNullOrEmpty(dto.Keyword),
                     d => d.Order.Title.Contains(dto.Keyword!) || d.Order.No.Contains(dto.Keyword!))

+ 0 - 1
src/Hotline.Application/Snapshot/Contracts/IOrderSnapshotApplication.cs

@@ -146,6 +146,5 @@ public interface IOrderSnapshotApplication
     Task UpdateIsEmphasisAsync(UpdateIsEmphasisInDto dto);
 
     Task GetOrderDetailAsync(string id, Share.Dtos.Order.OrderDto dto, CancellationToken token);
-
     Task<string> GetStartflowAsync(string? orderId, CancellationToken requestAborted);
 }

+ 2 - 0
src/Hotline.Application/Snapshot/IndustryApplication.cs

@@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Wordprocessing;
 using Hotline.Application.Snapshot.Contracts;
 using Hotline.Caching.Interfaces;
 using Hotline.File;
+using Hotline.FlowEngine.WorkflowModules;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Settings;
 using Hotline.Share.Attributes;
@@ -66,6 +67,7 @@ public class IndustryApplication : IIndustryApplication, IScopeDependency
                 .Then(async org => { dto.ApproveOrgName = org.Name; });
         }
         var entity = dto.Adapt<Industry>();
+        entity.ModuleCode = WorkflowModuleConsts.OrderHandle;
         var id = await _industryRepository.AddAsync(entity, cancellationToken);
         if (dto.Files.NotNullOrEmpty())
         {

+ 10 - 1
src/Hotline.Application/Snapshot/RedPackApplication.cs

@@ -245,12 +245,14 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
         var outDto = new SnapshotOrderAuditDetailOutDto { Order = order.Adapt<SnapshotOrderAuditOrderDetailOutDto>() };
         var industry = await _industryRepository.Queryable(includeDeleted: true)
             .LeftJoin<OrderSnapshot>((i, o) => i.Id == o.IndustryId)
-            .Select((i, o) => new { i.Id, i.CitizenReadPackAmount, i.ArgeePoints, i.ExtraDeductedPoints, i.RefusePoints })
+            .Where((i, o) => o.Id == id)
+            .Select((i, o) => new { i.Id, i.CitizenReadPackAmount, i.ArgeePoints, i.ExtraDeductedPoints, i.RefusePoints , i.IsPoints})
             .FirstAsync();
         outDto.Amount = industry.CitizenReadPackAmount;
         outDto.ArgeePoints = industry.ArgeePoints;
         outDto.ExtraDeductedPoints = industry.ExtraDeductedPoints;
         outDto.RefusePoints = industry.RefusePoints;
+        outDto.IsPoints = industry.IsPoints;
         outDto.RedPackTxt = $"{order.FromPhone}【】元; ";
         var dayStart = DateTime.Now.ToString("yyyy-MM-dd 00:00:00").ObjToDate();
         var dayEnd = DateTime.Now.ToString("yyyy-MM-dd 23:59:59").ObjToDate();
@@ -327,6 +329,7 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
                             County = order.County,
                             // IsRectify = s.IsRepetition
                             IsDeal = snapshot.IsDeal,
+                            IsSafetyDepartment = snapshot.IsSafetyDepartment,
                             NetworkENumber = snapshot.NetworkENumber,
                             IsTruth = snapshot.IsTruth,
                             IsTruthDepartment = snapshot.IsTruthDepartment,
@@ -339,9 +342,12 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
                             AuditOrgId = special.AuditOrgId,
                             AuditOrgName = special.AuditOrgName,
                             AuditRemark = special.AuditRemark,
+                            ReplenishAmount = supplement.ReplenishAmount,
                             BankCardNo = supplement.BankCardNo,
                             OpenBank = supplement.OpenBank,
+                            AwardName = supplement.Name,
                             AuditStatus = special.Status,
+                            AuditType = supplement.AuditType
                         });
 #if DEBUG
         var sql = query.ToSqlString();
@@ -618,6 +624,7 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
             .Then(async audit =>
             {
                 var orderNo = await _orderRepository.Queryable().Where(m => m.Id == audit.OrderId).Select(m => m.No).FirstAsync();
+                var auditTypeId = _systemDic.SnapshotRedPackSpecialType.FirstOrDefault(m => m.DicDataName.StartsWith(dto.AuditType))?.DicDataValue;
 
                 var entity = dto.Adapt<SupplementRecord>();
                 var industryName = await _orderSnapshotRepository.Queryable()
@@ -630,6 +637,8 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
                 entity.IndustryName = industryName.IndustryName;
                 entity.IndustryId = industryName.IndustryId;
                 entity.ReplenishRemark = dto.ReplenishRemark;
+                entity.AuditType = dto.AuditType;
+                entity.AuditTypeCode = auditTypeId;
                 await _supplementRecordRepository.AddAsync(entity);
 
                 if (dto.IsSendSMS)

+ 9 - 8
src/Hotline.Application/Snapshot/SnapshotOrderApplication.cs

@@ -1,4 +1,5 @@
 using Hotline.Caching.Interfaces;
+using Hotline.Configurations;
 using Hotline.File;
 using Hotline.FlowEngine.Notifications;
 using Hotline.FlowEngine.Workflows;
@@ -16,6 +17,7 @@ using Hotline.Share.Tools;
 using Hotline.Snapshot;
 using Hotline.Tools;
 using Mapster;
+using Microsoft.Extensions.Options;
 using Novacode.NETCorePort;
 using NPOI.POIFS.Properties;
 using SqlSugar;
@@ -225,8 +227,8 @@ public class SnapshotOrderApplication : IOrderSnapshotApplication, IScopeDepende
             .LeftJoin<Order>((snapshot, order) => snapshot.Id == order.Id)
             .LeftJoin<WorkflowStep>((snapshot, order, step) => step.ExternalId == order.Id && step.Tag == TagDefaults.OrderMark && step.Status != EWorkflowStepStatus.Handled)
             .Where((snapshot, order, step) => snapshot.IndustryName == "安全隐患")
-            .WhereIF(dto.Status == 1, (snapshot, order, step) => step.Id != null && snapshot.IsSafetyDepartment == null) // 待标记
-            .WhereIF(dto.Status == 2, (snapshot, order, step) => snapshot.IsSafetyDepartment != null) // 已标记
+            .WhereIF(dto.Status == 1, (snapshot, order, step) => step.Id != null && (step.HandlerId == _sessionContext.UserId ||_sessionContext.Roles.Contains(step.RoleId)) && snapshot.IsSafetyDepartment == null) // 待标记
+            .WhereIF(dto.Status == 2, (snapshot, order, step) => snapshot.IsSafetyDepartment != null && snapshot.SignUserId == _sessionContext.UserId) // 已标记
             .WhereIF(dto.No.NotNullOrEmpty(), (snapshot, order, step) => order.No.Contains(dto.No))
             .WhereIF(dto.Title.NotNullOrEmpty(), (snapshot, order, step) => order.Title.Contains(dto.Title))
             .OrderByDescending((snapshot, order, step) => snapshot.CreationTime)
@@ -321,6 +323,8 @@ public class SnapshotOrderApplication : IOrderSnapshotApplication, IScopeDepende
 
     public async Task SaveOrderWorkflowInfo(NextWorkflowDto<OrderHandleFlowDto> dto)
     {
+        if (_systemSettingCacheManager.Snapshot == false) return;
+        
         var snapshot = await _orderSnapshotRepository.GetAsync(dto.Data.OrderId);
         if (snapshot is null) return;
 
@@ -669,15 +673,11 @@ public class SnapshotOrderApplication : IOrderSnapshotApplication, IScopeDepende
             var order = await _orderSnapshotRepository.Queryable()
                 .LeftJoin<Industry>((snapshot, industry) => snapshot.IndustryId == industry.Id)
                 .Where((snapshot, industry) => snapshot.Id == orderId)
-                .Select((snapshot, industry) => new { snapshot.Id, industry.IndustryType })
+                .Select((snapshot, industry) => new { snapshot.Id, industry.ModuleCode })
                 .FirstAsync(token);
             if (order == null) return WorkflowModuleConsts.OrderHandle;
 
-            if (order.IndustryType == EIndustryType.Declare) // 作业申报类型
-            {
-                return WorkflowModuleConsts.OrderHandleSnapshot;
-            }
-            return WorkflowModuleConsts.OrderHandle;
+            return order.ModuleCode ?? WorkflowModuleConsts.OrderHandle;
         }
         catch (Exception e)
         {
@@ -685,4 +685,5 @@ public class SnapshotOrderApplication : IOrderSnapshotApplication, IScopeDepende
             return WorkflowModuleConsts.OrderHandle;
         }
     }
+
 }

+ 1 - 1
src/Hotline.Repository.SqlSugar/System/SystemLogRepository.cs

@@ -29,7 +29,7 @@ public class SystemLogRepository : BaseRepository<SystemLog>, ISystemLogReposito
                 ExecuteParam = executeParam,
                 ExecuteResult = executeResult,
                 ExecuteUrl = executeUrl,
-                Remark = remark.Substring(0, 255),
+                Remark = remark.Length > 255 ? remark.Substring(0, 255) : remark,
                 Status = status,
                 IpUrl = ipUrl
             };

+ 5 - 0
src/Hotline.Share/Dtos/CallCenter/QueryCallsFixedDto.cs

@@ -81,5 +81,10 @@ namespace Hotline.Share.Dtos.CallCenter
         /// 排序方式 0 升序 1 降序
         /// </summary>
         public int? SortRule { get; set; }
+
+        /// <summary>
+        /// 通话记录编号
+        /// </summary>
+        public string? CallNo { get; set; }
     }
 }

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

@@ -146,6 +146,10 @@ public class OrderFlowTraceDto
 
     #endregion
 
+    /// <summary>
+    /// 发布状态、回访结果
+    /// </summary>
+    public string? OpinionResult {  get; set; }
 }
 
 /// <summary>

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

@@ -941,6 +941,11 @@ namespace Hotline.Share.Dtos.Order
         /// </summary>
         public string SendBackOpinion { get; set; }
 
+        /// <summary>
+        /// 重办意见
+        /// </summary>
+        public string? ReTransactOpinion { get; set; }
+
         /// <summary>
         /// 退回原因
         /// </summary>

+ 21 - 1
src/Hotline.Share/Dtos/Snapshot/OrderDto.cs

@@ -466,6 +466,18 @@ public class SnapshotOrderAuditItemsOutDto
     /// 奖励人姓名
     /// </summary>
     public string? AwardName { get; set; }
+
+    /// <summary>
+    /// 标记是否安全生产
+    /// </summary>
+    public bool? IsSafetyDepartment { get; set; }
+
+    public string? IsSafetyDepartmentTxt => IsSafetyDepartment.HasValue ? (IsSafetyDepartment.Value ? "是" : "否") : string.Empty;
+
+    /// <summary>
+    /// 特殊红包审核,审批类型
+    /// </summary>
+    public string? AuditType { get; set; }
 }
 
 /// <summary>
@@ -1025,7 +1037,7 @@ public class UpdateRedPackAuditInDto
     /// <summary>
     /// 积分审核状态
     /// </summary>
-    public ESnapshotSMSStatus PointsStatus { get; set; }
+    public ESnapshotSMSStatus? PointsStatus { get; set; }
 
     /// <summary>
     /// 积分
@@ -1751,6 +1763,14 @@ public class OrderSignBathInDto
     /// 备注
     /// </summary>
     public string Remark { get; set; }
+
+    /// <summary>
+    /// 状态;
+    /// 0: 全部;
+    /// 1: 待标签;
+    /// 2: 已标签;
+    /// </summary>
+    public int Status { get; set; }
 }
 
 public record LabelOrderSnapshotLogItemsInDto : PagedRequest

+ 2 - 0
src/Hotline.Share/Dtos/Snapshot/RedPackDto.cs

@@ -151,6 +151,8 @@ public class UpdateRedPackRecordInDto
     /// 补充发放类型Id
     /// </summary>
     public string ReplenishTypeId { get; set; }
+
+    public string AuditType { get; set; }
 }
 
 

+ 6 - 1
src/Hotline.Share/Enums/FlowEngine/EFlowDirection.cs

@@ -22,5 +22,10 @@ public enum EFlowDirection
     /// <summary>
     /// 已归档回到部门
     /// </summary>
-    FiledToOrg = 7
+    FiledToOrg = 7,
+
+    /// <summary>
+    /// 其他(流程模板配置为其他时)
+    /// </summary>
+    Other = 99
 }

+ 6 - 0
src/Hotline.Share/Enums/FlowEngine/EHandleMode.cs

@@ -66,4 +66,10 @@ public enum EHandleMode
     /// </summary>
     [Description("二次办理")]
     SecondaryHandle = 202,
+
+    /// <summary>
+    /// 发布退回
+    /// </summary>
+    [Description("发布退回")]
+    PublishPrevious = 203,
 }

+ 6 - 0
src/Hotline.Share/Enums/FlowEngine/EWorkflowTraceType.cs

@@ -56,5 +56,11 @@ namespace Hotline.Share.Enums.FlowEngine
         /// </summary>
         [Description("二次办理")]
         SecondHandle = 7,
+
+        /// <summary>
+        /// 发布退回
+        /// </summary>
+        [Description("发布退回")]
+        PublishPrevious = 8,
     }
 }

+ 1 - 1
src/Hotline.Share/Tools/EnumExtensions.cs

@@ -48,7 +48,7 @@ public static class EnumExtensions
     public static List<KeyValuePair<int, string>> GetEnumKeyValueList<TEnum>() where TEnum : Enum
     {
         // 按照枚举定义的顺序获取键值对
-        return typeof(ESeatEvaluate)
+        return typeof(TEnum)
              .GetFields()
              .Where(f => f.IsLiteral) // 过滤出枚举字段
              .Select(f =>

+ 1 - 1
src/Hotline/FlowEngine/WorkflowModules/WorkflowModuleConsts.cs

@@ -70,7 +70,7 @@ public class WorkflowModuleConsts
     public const string OrderHandleSnapshot = "OrderHandleSnapshot";
 
 
-	public static List<WorkflowModule> AllModules =>
+    public static List<WorkflowModule> AllModules =>
         new()
         {
             new(OrderHandle, "工单办理"),

+ 11 - 9
src/Hotline/FlowEngine/Workflows/WorkflowDomainService.cs

@@ -1317,8 +1317,7 @@ namespace Hotline.FlowEngine.Workflows
                         EBusinessType.Department => EFlowDirection.CenterToOrg,
                         EBusinessType.DepartmentLeader => EFlowDirection.CenterToOrg,
                         EBusinessType.File => EFlowDirection.CenterToFile,
-                        _ => throw new ArgumentOutOfRangeException(nameof(directionStepBusinessType),
-                            directionStepBusinessType, null)
+                        _ => EFlowDirection.Other
                     };
                 case EBusinessType.Department:
                 case EBusinessType.DepartmentLeader:
@@ -1331,8 +1330,7 @@ namespace Hotline.FlowEngine.Workflows
                         EBusinessType.Department => EFlowDirection.OrgToOrg,
                         EBusinessType.DepartmentLeader => EFlowDirection.OrgToOrg,
                         EBusinessType.File => EFlowDirection.OrgToFile,
-                        _ => throw new ArgumentOutOfRangeException(nameof(directionStepBusinessType),
-                            directionStepBusinessType, null)
+                        _ => EFlowDirection.Other
                     };
                 case EBusinessType.File:
                     return directionStepBusinessType switch
@@ -1343,14 +1341,14 @@ namespace Hotline.FlowEngine.Workflows
                         EBusinessType.DepartmentLeader => EFlowDirection.FiledToOrg,
                         EBusinessType.CenterMonitor => EFlowDirection.FiledToCenter,
                         EBusinessType.CenterLeader => EFlowDirection.FiledToCenter,
-                        _ => throw new ArgumentOutOfRangeException(nameof(directionStepBusinessType), directionStepBusinessType, null)
+                        _ => EFlowDirection.Other
                     };
                 case EBusinessType.Unknown:
                 case EBusinessType.Publish:
                 case EBusinessType.Visit:
                 case EBusinessType.TrashEnd:
                 default:
-                    throw new ArgumentOutOfRangeException(nameof(sourceStepBusinessType), sourceStepBusinessType, null);
+                    return EFlowDirection.Other;
             }
         }
 
@@ -1647,7 +1645,8 @@ namespace Hotline.FlowEngine.Workflows
                               workflow.Steps.MaxBy(d => d.CreationTime);
 
             //update uncomplete traces
-            var uncompleteTraces = workflow.Traces.Where(d => d.Status != EWorkflowStepStatus.Handled && d.TraceStyle == ETraceStyle.Flow).ToList();
+            //var uncompleteTraces = workflow.Traces.Where(d => d.Status != EWorkflowStepStatus.Handled && d.TraceStyle == ETraceStyle.Flow).ToList();
+            var uncompleteTraces = workflow.Traces.Where(d => d.Status != EWorkflowStepStatus.Handled).ToList();
             if (uncompleteTraces.Any())
             {
                 foreach (var trace in uncompleteTraces)
@@ -1664,10 +1663,13 @@ namespace Hotline.FlowEngine.Workflows
             }
             else
             {
-                var endTrace = workflow.Traces.Where(d => d.StepType == EStepType.End && d.TraceStyle == ETraceStyle.Flow).MaxBy(d => d.CreationTime);
+                //var endTrace = workflow.Traces.Where(d => d.StepType == EStepType.End && d.TraceStyle == ETraceStyle.Flow).MaxBy(d => d.CreationTime);
+                var endTrace = workflow.Traces.Where(d => d.TraceStyle == ETraceStyle.TrashEnd).MaxBy(d => d.CreationTime);
                 if (endTrace is not null)
                 {
-                    endTrace.Opinion += ("\r\n" + dto.Opinion);
+                    endTrace.HandleMode = handleMode;
+                    //endTrace.Opinion += ("\r\n" + dto.Opinion);
+                    endTrace.Opinion = dto.Opinion;
                     updateTraces.Add(endTrace);
                 }
             }

+ 1 - 1
src/Hotline/Identity/IdentityDomainService.cs

@@ -32,7 +32,7 @@ public class IdentityDomainService : IIdentityDomainService, IScopeDependency
         if (string.IsNullOrEmpty(request.Nonce)) return false;
         var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
         _logger.LogInformation($"now:{now}, req:{request.Timestamp}");
-        if (request.Timestamp > now) return false;
+        //if ((request.Timestamp - now) > 3) return false;
         if ((now - request.Timestamp) >= 60) return false;
         var nonce = _cacheAccountNonce.Get(request.Username)?.Nonce;
         _logger.LogInformation($"nonce:{nonce}, reqnonce:{request.Nonce}");

+ 1 - 0
src/Hotline/Orders/OrderVisitDetail.cs

@@ -80,6 +80,7 @@ namespace Hotline.Orders
         /// <summary>
         /// 回访内容
         /// </summary>
+        [SugarColumn(ColumnDataType = "varchar(8000)")]
         public string? VisitContent { get; set; }
 
         /// <summary>

+ 4 - 4
src/Hotline/SeedData/SystemDicDataSeedData.cs

@@ -32,10 +32,10 @@ public class SystemDicDataSeedData : ISeedData<SystemDicData>
         if (dicTypeCode == SysDicTypeConsts.SnapshotRedPackSpecialType)
         {
             return [
-                new() {  Id = "08dd4bf7-b7c6-471b-8ee5-deb5a1c4776a", DicDataValue = "dqh", DicDataName = "电气焊类", Sort = 1},
-                new() {  Id = "08dd4bf7-b7ab-4729-80b2-b2c5db5d221c", DicDataValue = "qp", DicDataName = "气瓶类", Sort = 2},
-                new() {  Id = "08dd4bf7-b352-4b52-8a96-78f73197c22e", DicDataValue = "dde", DicDataName = "电动车类", Sort = 3},
-                new() {  Id = "08dd4bf7-b349-48ea-8f54-fb8b29070fa3", DicDataValue = "xftd", DicDataName = "消防通道", Sort = 4},
+                new() {  Id = "08dd4bf7-b7c6-471b-8ee5-deb5a1c4776a", DicDataValue = "dqh", DicDataName = "电气焊类|1", Sort = 1},
+                new() {  Id = "08dd4bf7-b7ab-4729-80b2-b2c5db5d221c", DicDataValue = "qp", DicDataName = "气瓶类|1", Sort = 2},
+                new() {  Id = "08dd4bf7-b352-4b52-8a96-78f73197c22e", DicDataValue = "dde", DicDataName = "电动车类|1", Sort = 3},
+                new() {  Id = "08dd4bf7-b349-48ea-8f54-fb8b29070fa3", DicDataValue = "xftd", DicDataName = "消防通道|1", Sort = 4},
                 ];
         }
         if (dicTypeCode == SysDicTypeConsts.SnapshotOrderLabel)

+ 1 - 1
src/Hotline/Snapshot/Contracts/ISnapshotPointsDomainService.cs

@@ -12,5 +12,5 @@ namespace Hotline.Snapshot.Contracts;
 /// </summary>
 public interface ISnapshotPointsDomainService
 {
-    Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus status, int? extraDeductedPoints);
+    Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus? status, int? extraDeductedPoints);
 }

+ 6 - 0
src/Hotline/Snapshot/Industry.cs

@@ -202,4 +202,10 @@ public class Industry : CreationSoftDeleteEntity
     /// </summary>
     [SugarColumn(ColumnDescription = "额外扣除积分")]
     public int? ExtraDeductedPoints { get; set; }
+
+    /// <summary>
+    /// 流程模板Code
+    /// </summary>
+    [SugarColumn(ColumnDescription = "流程模板Code")]
+    public string? ModuleCode { get; set; }
 }

+ 2 - 1
src/Hotline/Snapshot/Services/SnapshotPointsDomainService.cs

@@ -22,8 +22,9 @@ public class SnapshotPointsDomainService : ISnapshotPointsDomainService, IScopeD
         _pointsRecordRepository = snapshotPointsRecordRepository;
     }
 
-    public async Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus status, int? extraDeductedPoints)
+    public async Task AddPointsAsync(string orderId, EPointsSource source, ESnapshotSMSStatus? status, int? extraDeductedPoints)
     {
+        if (status == null) return;
         var order = await _orderSnapshotRepository.Queryable()
             .LeftJoin<Industry>((snapshot, industry) => snapshot.IndustryId == industry.Id)
             .Where((snapshot, industry) => snapshot.Id == orderId)

+ 2 - 0
test/Hotline.Tests/Application/IndustryApplicationTest.cs

@@ -68,6 +68,8 @@ public class IndustryApplicationTest : TestBase
         });
         updateIndustry.IsPoints.ShouldBe(false);
         await _industryApplication.UpdateIndustryAsync(item.Adapt<UpdateIndustryInDto>(), CancellationToken.None);
+        var changeItem = await _industryRepository.GetAsync(industry.Id);
+        changeItem.ModuleCode.ShouldNotBeNull();
     }
 
     [Fact]

+ 21 - 1
test/Hotline.Tests/Application/OrderSnapshotApplicationTest.cs

@@ -1,6 +1,7 @@
 using Hotline.Api.Controllers;
 using Hotline.Application.Snapshot.Contracts;
 using Hotline.Caching.Interfaces;
+using Hotline.FlowEngine.WorkflowModules;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
@@ -75,6 +76,23 @@ public class OrderSnapshotApplicationTest : TestBase
         };
     }
 
+    /// <summary>
+    /// 随手拍网格员超时:
+    /// </summary>
+    /// <returns></returns>
+    [Fact]
+    public async Task SnapshotWorkflow_WorkflowModuleError_est()
+    {
+        var order = _orderServiceMock.CreateSnapshotOrder(SetWeiXin)
+            .办理到一级部门(SetZuoXi)
+            .StepHandle(async order =>
+            {
+                var detail = await _orderController.Get(order.Id);
+                detail.Workflow.ModuleCode.ShouldBe(WorkflowModuleConsts.OrderHandleSnapshot);
+            }
+            ).GetCreateResult();
+    }
+
     /// <summary>
     /// 随手拍网格员超时:
     /// </summary>
@@ -216,6 +234,7 @@ public class OrderSnapshotApplicationTest : TestBase
                 var specialRedAudit = specialRedAuditItems.FirstOrDefault();
                 specialRedAudit.ShouldNotBeNull();
                 var a = _systemDicDataCacheManager.SnapshotReplenishType.First();
+                var b = _systemDicDataCacheManager.SnapshotRedPackSpecialType.First();
                 var inDto = new UpdateRedPackRecordInDto
                 {
                     RedPackAuditId = baseData.RedPackAuditId,
@@ -227,7 +246,8 @@ public class OrderSnapshotApplicationTest : TestBase
                     ReplenishRemark = "补充发放备注",
                     IsSendSMS = false,
                     ReplenishType = a.DicDataName,
-                    ReplenishTypeId = a.DicDataValue
+                    ReplenishTypeId = a.DicDataValue,
+                    AuditType = b.DicDataName,
                 };
 
                 await _redPackApplication.UpdateRedPackSpecialRecordAsync(inDto);

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

@@ -71,12 +71,12 @@ public class OrderServiceMock
         _systemDicDataCacheManager = systemDicDataCacheManager;
     }
 
-    public IOrderServiceStartWorkflow CreateSnapshotOrder(Action action)
+    public IOrderServiceStartWorkflow CreateSnapshotOrder(Action action, string industryName = "电气焊作业申报")
     {
         action.Invoke();
         var homePage = _snapshotController.GetHomePageAsync().GetAwaiter().GetResult();
         var industry = homePage.Industrys
-            .Where(m => m.IndustryType == EIndustryType.Clue)
+            .Where(m => m.Name == industryName)
             .OrderBy(m => m.DisplayOrder)
             .FirstOrDefault();
         var pageBase = _snapshotController.GetIndustryBaseAsync(industry.Id).GetAwaiter().GetResult();