Browse Source

Merge branch 'test' into lib/test

libin 3 months ago
parent
commit
abab13ee18
43 changed files with 792 additions and 144 deletions
  1. 3 2
      src/Hotline.Api/Controllers/Bi/BiOrderController.cs
  2. 8 1
      src/Hotline.Api/Controllers/Bigscreen/DataScreenController.cs
  3. 42 8
      src/Hotline.Api/Controllers/OrderController.cs
  4. 48 10
      src/Hotline.Api/Controllers/Snapshot/RedPackController.cs
  5. 22 0
      src/Hotline.Api/Controllers/Snapshot/SnapshotController.cs
  6. 3 3
      src/Hotline.Api/Controllers/Snapshot/SnapshotOrderController.cs
  7. 3 2
      src/Hotline.Api/Controllers/TestController.cs
  8. 2 6
      src/Hotline.Api/Controllers/WebPortalController.cs
  9. 3 0
      src/Hotline.Api/Hotline.Api.csproj
  10. 2 2
      src/Hotline.Application.Contracts/Validators/Order/AddOrderDtoValidator.cs
  11. 15 0
      src/Hotline.Application.Tests/Application/RedPackApplicationTest.cs
  12. 52 0
      src/Hotline.Application.Tests/Controller/OrderControllerTest.cs
  13. 32 22
      src/Hotline.Application/CallCenter/DefaultCallApplication.cs
  14. 1 1
      src/Hotline.Application/CallCenter/ICallApplication.cs
  15. 2 2
      src/Hotline.Application/CallCenter/TianRunCallApplication.cs
  16. 25 4
      src/Hotline.Application/Orders/OrderApplication.cs
  17. 11 1
      src/Hotline.Application/Snapshot/IOrderSnapshotApplication.cs
  18. 3 1
      src/Hotline.Application/Snapshot/IRedPackApplication.cs
  19. 17 6
      src/Hotline.Application/Snapshot/OrderSnapshotApplication.cs
  20. 34 7
      src/Hotline.Application/Snapshot/RedPackApplication.cs
  21. 9 4
      src/Hotline.Application/Snapshot/SnapshotApplicationBase.cs
  22. 1 1
      src/Hotline.Application/StatisticalReport/OrderReportApplication.cs
  23. 1 1
      src/Hotline.Repository.SqlSugar/CallCenter/TrCallRecordRepository.cs
  24. 19 14
      src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs
  25. 9 0
      src/Hotline.Repository.SqlSugar/Snapshot/IndustryRepository.cs
  26. 18 0
      src/Hotline.Repository.SqlSugar/Snapshot/SupplementRecordRepository.cs
  27. 1 1
      src/Hotline.Share/Dtos/CallCenter/BiQueryCallsDto.cs
  28. 13 0
      src/Hotline.Share/Dtos/CallCenter/CallDto.cs
  29. 1 1
      src/Hotline.Share/Dtos/Order/OrderBiDto.cs
  30. 1 1
      src/Hotline.Share/Dtos/Order/OrderStartFlowDto.cs
  31. 5 0
      src/Hotline.Share/Dtos/Order/Publish/QueryOrderPublishDto.cs
  32. 86 3
      src/Hotline.Share/Dtos/Snapshot/OrderDeclareDto.cs
  33. 12 2
      src/Hotline.Share/Dtos/Snapshot/OrderDto.cs
  34. 122 1
      src/Hotline.Share/Dtos/Snapshot/RedPackDto.cs
  35. 29 0
      src/Hotline.Share/Enums/Snapshot/EJobType.cs
  36. 4 1
      src/Hotline.Share/Requests/PagedKeywordRequest.cs
  37. 5 2
      src/Hotline/Orders/DatabaseEventHandler/OrderVisitDetailEventHandler.cs
  38. 1 0
      src/Hotline/Snapshot/Interfaces/IIndustryRepository.cs
  39. 11 0
      src/Hotline/Snapshot/Interfaces/ISupplementRecordRepository.cs
  40. 14 3
      src/Hotline/Snapshot/OrderSnapshot.cs
  41. 0 30
      src/Hotline/Snapshot/RedPackAudit.cs
  42. 101 0
      src/Hotline/Snapshot/SupplementRecord.cs
  43. 1 1
      src/Tr.Sdk/Tr.Sdk.csproj

+ 3 - 2
src/Hotline.Api/Controllers/Bi/BiOrderController.cs

@@ -901,10 +901,11 @@ namespace Hotline.Api.Controllers.Bi
             {
                 OrgName = "合计",
                 OrgCode = "",
-                AllTotal = list.Sum(p => p.AllTotal),
+                //AllTotal = list.Sum(p => p.AllTotal),
                 PassTotal = list.Sum(p => p.PassTotal),
                 NoPassTotal = list.Sum(p => p.NoPassTotal),
-                ExaminingTotal = list.Sum(p => p.ExaminingTotal)
+                ExaminingTotal = list.Sum(p => p.ExaminingTotal),
+                WithdrawTotal = list.Sum(p=> p.WithdrawTotal)
             });
 
             var orderDtos = _mapper.Map<ICollection<BiOrderDelayDataDto>>(list);

+ 8 - 1
src/Hotline.Api/Controllers/Bigscreen/DataScreenController.cs

@@ -10,6 +10,7 @@ using Hotline.Share.Dtos.Bigscreen;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Enums.KnowledgeBase;
 using Hotline.Share.Enums.Order;
+using JiebaNet.Segmenter.Common;
 using MapsterMapper;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
@@ -617,7 +618,13 @@ namespace Hotline.Api.Controllers.Bigscreen
 
                 OrderOverdueCount = await _orderSecondaryHandlingRepository.Queryable()
                 .Includes(x => x.Order)
-                 .Where(x => x.Order.ExpiredStatus == EExpiredStatus.Expired && x.AuditTime >= StartTime && x.AuditTime <= EndTime
+                 //.Where(x => x.Order.Status < EOrderStatus.Filed)
+                 .Where(x => x.Order.ExpiredTime != null &&
+                        (((x.Order.Status == EOrderStatus.Filed || x.Order.Status == EOrderStatus.Published || x.Order.Status == EOrderStatus.Visited) &&
+                           x.Order.FiledTime >= x.Order.ExpiredTime) ||
+                         ((x.Order.Status != EOrderStatus.Filed && x.Order.Status != EOrderStatus.Published && x.Order.Status != EOrderStatus.Visited) &&
+                          dateTime >= x.Order.ExpiredTime.Value)))
+                 .Where(x => x.AuditTime >= StartTime && x.AuditTime <= EndTime
                  && x.State != ESecondaryHandlingState.NotApply
                  && x.State != ESecondaryHandlingState.Apply && x.State != ESecondaryHandlingState.Refuse)
                  .CountAsync(),

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

@@ -1318,7 +1318,7 @@ public class OrderController : BaseController
     public async Task Visit([FromBody] VisitDto dto)
     {
         // 发送延迟关联通话记录消息
-        await _callApplication.PublishVisitRelevanceCallIdAsync(dto.Adapt<OrderRelevanceCallIdDto>(), HttpContext.RequestAborted);
+        dto.CallId = await _callApplication.PublishVisitRelevanceCallIdAsync(dto.Adapt<OrderRelevanceCallIdDto>(), HttpContext.RequestAborted);
         dto.CallId = await _callApplication.GetOrSetCallIdAsync(dto.CallId, HttpContext.RequestAborted);
         await _orderApplication.SaveOrderVisit(dto, HttpContext.RequestAborted);
     }
@@ -2083,8 +2083,12 @@ public class OrderController : BaseController
 			try
 			{
                 var workflow = dto.NextWorkflow;
-				var delay = await _orderDelayRepository.GetAsync(item, HttpContext.RequestAborted);
+				var delay = await _orderDelayRepository.Queryable().Includes(x=>x.Order).Where(x=>x.Id == item).FirstAsync(HttpContext.RequestAborted);
 				workflow.WorkflowId = delay.WorkflowId;
+				var workflowEntuty = await _workflowDomainService.GetWorkflowAsync(workflow.WorkflowId, withDefine: true, withSteps: true,cancellationToken: HttpContext.RequestAborted);
+				var currentStep =
+					workflowEntuty.Steps.FirstOrDefault(d => d.Status == EWorkflowStepStatus.WaitForAccept || d.Status == EWorkflowStepStatus.WaitForHandle);
+
 				NextStepsWithOpinionDto<NextStepOption> next = null;
 
 				try
@@ -2104,7 +2108,23 @@ public class OrderController : BaseController
 					}
 				}
 				if (next == null) continue;
-               
+
+				if (!delay.Order.IsProvince)
+				{
+					if (next.Steps.Any(x => x.Value == "省审批"))
+					{
+						next.Steps.Remove(next.Steps.First(x => x.Value == "省审批"));
+					}
+				}
+
+				if (!_sessionContext.OrgIsCenter && currentStep.Name != "中心初审")
+				{
+					if (next.Steps.Any(x => x.Value == "中心终审"))
+					{
+						next.Steps.Remove(next.Steps.First(x => x.Value == "中心终审"));
+					}
+				}
+
 				var isBatch = next.Steps.Where(x => x.Value == workflow.NextStepName).Any();
                 if (isBatch)
                 {
@@ -4177,23 +4197,36 @@ public class OrderController : BaseController
             var order = await _orderRepository.GetAsync(orderId, HttpContext.RequestAborted);
             if (order is null)
             {
-                stringBuilder.Append($"工单:{orderId} 不存在");
                 continue;
             }
-
-            var snapshot = await _orderSnapshotRepository.UpdateSafetyAsync(orderId, dto.IsSafetyDepartment, dto.Remark);
+            var snapshot = await _orderSnapshotApplication.UpdateSafetyAsync(orderId, dto.IsSafetyDepartment, dto.Remark);
             if (snapshot is null)
             {
-                stringBuilder.Append($"随手拍: {orderId} 不存在");
+                stringBuilder.Append($"随手拍: {order.No} 不存在");
+                continue;
             }
             var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withDefine: true, withSteps: true, withTraces: true,
     cancellationToken: HttpContext.RequestAborted);
 
-            var nextSteps = await _workflowApplication.GetNextStepsAsync(order.WorkflowId, HttpContext.RequestAborted);
+            NextStepsWithOpinionDto<NextStepOption> nextSteps;
+            try
+            {
+                nextSteps = await _workflowApplication.GetNextStepsAsync(order.WorkflowId, HttpContext.RequestAborted);
+            }
+            catch (UserFriendlyException e)
+            {
+                if (e.Message.Contains("未找到对应节点"))
+                {
+                    stringBuilder.AppendLine($"{order.No} 修改成功");
+                    continue;
+                }
+                throw;
+            }            
             var stepInfo = nextSteps.Steps.FirstOrDefault(m => m.BusinessType == EBusinessType.Send);
             if (stepInfo == null)
             {
                 stringBuilder.Append($"下一步节点: [派单组] 未找到");
+                continue;
             }
             var data = new OrderHandleFlowDto
             {
@@ -4472,6 +4505,7 @@ public class OrderController : BaseController
     [HttpPost("steps/temp")]
     public async Task TempSaveAsync([FromBody] StepTempInDto dto)
     {
+        if (dto.OrderId.IsNullOrEmpty() || dto.Opinion.IsNullOrEmpty()) return;
         await _typeCache.SetAsync($"tmp_opinion_{dto.OrderId}{_sessionContext.UserId}", dto.Opinion, TimeSpan.FromDays(3),
             HttpContext.RequestAborted);
     }

+ 48 - 10
src/Hotline.Api/Controllers/Snapshot/RedPackController.cs

@@ -18,13 +18,15 @@ public class RedPackController : BaseController
     private readonly IIndustryRepository _industryRepository;
     private readonly ISystemDicDataCacheManager _sysDic;
     private readonly ISnapshotSMSTemplateRepository _snapshotSMSTemplateRepository;
+    private readonly IOrderSnapshotRepository _orderSnapshotRepository;
 
-    public RedPackController(IRedPackApplication redPackApplication, IIndustryRepository industryRepository, ISystemDicDataCacheManager sysDic, ISnapshotSMSTemplateRepository snapshotSMSTemplateRepository)
+    public RedPackController(IRedPackApplication redPackApplication, IIndustryRepository industryRepository, ISystemDicDataCacheManager sysDic, ISnapshotSMSTemplateRepository snapshotSMSTemplateRepository, IOrderSnapshotRepository orderSnapshotRepository)
     {
         _redPackApplication = redPackApplication;
         _industryRepository = industryRepository;
         _sysDic = sysDic;
         _snapshotSMSTemplateRepository = snapshotSMSTemplateRepository;
+        _orderSnapshotRepository = orderSnapshotRepository;
     }
 
     #region 红包审核
@@ -63,7 +65,7 @@ public class RedPackController : BaseController
         => await _redPackApplication.AuditRedPackGuiderAuditAsync(dto);
 
     /// <summary>
-    /// 获取审核详情
+    /// 获取审核市民详情
     /// </summary>
     /// <param name="id">工单Id</param>
     /// <returns></returns>
@@ -107,13 +109,32 @@ public class RedPackController : BaseController
     /// 添加补充发放信息页面基础信息
     /// </summary>
     /// <returns></returns>
-    [HttpGet("record/basedata")]
-    public async Task<Dictionary<string, object>> UpdateRedPackRecordBaseDataAsync()
-    { 
-        return new Dictionary<string, object>()
+    [HttpGet("record/basedata/{id}")]
+    public async Task<Dictionary<string, object>> UpdateRedPackRecordBaseDataAsync(string id)
+    {
+        var snapshot = await _orderSnapshotRepository.Queryable()
+            .Where(m => m.Id == id)
+            .Select(m => new
+            {
+                m.Id,
+                m.AwardBankCardNo,
+                m.AwardOpenBank,
+                m.AwardName,
+                m.AwardAmount
+            })
+            .FirstAsync();
+        var dic = new Dictionary<string, object>()
         {
             { "replenishType", _sysDic.SnapshotReplenishType }
         };
+        if (snapshot != null)
+        {
+            dic.Add("bankCardNo", snapshot.AwardBankCardNo);
+            dic.Add("openBank", snapshot.AwardOpenBank);
+            dic.Add("name", snapshot.AwardName);
+            dic.Add("amount", snapshot.AwardAmount);
+        }
+        return dic;
     }
 
     /// <summary>
@@ -125,6 +146,25 @@ public class RedPackController : BaseController
     public async Task UpdateRedPackRecordAsync([FromBody] UpdateRedPackRecordInDto dto)
         => await _redPackApplication.UpdateRedPackRecordAsync(dto);
 
+    /// <summary>
+    /// 补充发放集合基础信息
+    /// </summary>
+    [HttpGet("record/supplement/basedata")]
+    public async Task<Dictionary<string, object>> GetRedPackRecordSupplementBaseDataAsync()
+    {
+        return new Dictionary<string, object>()
+        {
+            { "industry", await _industryRepository.GetDataBaseAsync() }
+        };
+    }
+
+    /// <summary>
+    /// 补充发放集合
+    /// </summary>
+    [HttpGet("record/supplement")]
+    public async Task<PagedDto<SnapshotRedPackRecordSupplementItemsOutDto>> GetRedPackRecordSupplementItemsAsync([FromQuery] SnapshotRedPackRecordSupplementItemsInDto dto)
+        => (await _redPackApplication.GetRedPackRecordSupplementItemsAsync(dto).ToPagedListAsync(dto)).ToPaged();
+
     /// <summary>
     /// 红包审核通过或拒绝
     /// </summary>
@@ -139,7 +179,7 @@ public class RedPackController : BaseController
     /// </summary>
     /// <returns></returns>
     [HttpGet("audit/sms_template")]
-    public async Task<IList<GetRedPackAuditSMSTemplateOutDto>> GetRedPackAuditSMSTemplateAsync([FromQuery]GetRedPackAuditSMSTemplateInDto dto)
+    public async Task<IList<GetRedPackAuditSMSTemplateOutDto>> GetRedPackAuditSMSTemplateAsync([FromQuery] GetRedPackAuditSMSTemplateInDto dto)
         => await _redPackApplication.GetRedPackAuditSMSTemplateAsync(dto);
 
     /// <summary>
@@ -149,9 +189,7 @@ public class RedPackController : BaseController
     [HttpGet("audit/basedata")]
     public async Task<Dictionary<string, object>> GetAuditBaseDataAsync()
     {
-        var industry = await _industryRepository.Queryable()
-            .Select(m => new { m.Id, m.Name })
-            .ToListAsync();
+        var industry = await _industryRepository.GetDataBaseAsync();
 
         var configAmount = await _industryRepository.Queryable()
             .Select(m => m.CitizenReadPackAmount)

+ 22 - 0
src/Hotline.Api/Controllers/Snapshot/SnapshotController.cs

@@ -371,6 +371,28 @@ public class SnapshotController : BaseController
     [AllowAnonymous]
     public async Task<OpenResponse> GetOrderDeclareItemsAsync([FromBody] OrderDeclareItemsInDto dto)
     {
+        var disposeDate = dto.JsonData.AcceptContent.DisposeDate.ObjToDate();
+        var industryId = await _industryRepository.Queryable()
+            .Where(m => m.IndustryType == EIndustryType.Declare)
+            .Select(m => m.Id)
+            .ToListAsync();
+        var result = await _orderSnapshotRepository.Queryable()
+            .LeftJoin<Order>((snapshot, order) => order.Id == snapshot.Id)
+            .Where((snapshot, order) => industryId.Contains(snapshot.IndustryId))
+            .WhereIF(dto.JsonData.AcceptContent.Tyep == 2, (snapshot, order) => order.CreationTime.Date == disposeDate.Date)
+            .WhereIF(dto.JsonData.AcceptContent.Tyep == 1, (snapshot, order) => order.FiledTime != null && order.FiledTime.Value.Date == disposeDate.Date)
+            .Select((snapshot, order) => new OrderDeclareItemsOutDto
+            { 
+                AreaCode = order.AreaCode,
+                AreaName = order.County,
+                EventType = 0,
+                WorkAddress = order.Address,
+                CreatedTime = order.CreationTime,
+                WorkType = snapshot.JobType.ObjToInt(),
+            })
+            .ToListAsync();
+
+
         return OpenResponse.Ok(new List<WebPortalDeResponse<List<OrderDeclareItemsOutDto>>>()
         {
             new() { code = "1", msg = "ok", data =

+ 3 - 3
src/Hotline.Api/Controllers/Snapshot/SnapshotOrderController.cs

@@ -112,13 +112,13 @@ public class SnapshotOrderController : BaseController
         => (await _orderSnapshotApplication.GetGuiderReplyItemsAsync(dto).ToPagedListAsync(dto)).ToPaged();
 
     /// <summary>
-    /// 获取工单标集合
+    /// 获取工单标集合
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
     [HttpGet("label")]
-    public async Task<PagedDto<LabelOrderSnapshotItemsOutDto>> GetLabelOrderSnapshotItemsAsync([FromQuery] LabelOrderSnapshotItemsInDto dto)
-        => (await _orderSnapshotApplication.GetLabelOrderSnapshotItemsAsync(dto).ToPagedListAsync(dto)).ToPaged();
+    public async Task<PagedDto<SignOrderSnapshotItemsOutDto>> GetSignOrderSnapshotItemsAsync([FromQuery] SignOrderSnapshotItemsInDto dto)
+        => (await _orderSnapshotApplication.GetSignOrderSnapshotItemsAsync(dto).ToPagedListAsync(dto)).ToPaged();
 
     /// <summary>
     /// 获取工单已经标签集合

+ 3 - 2
src/Hotline.Api/Controllers/TestController.cs

@@ -553,9 +553,10 @@ ICallApplication callApplication,
         //_capPublisher.PublishDelay((DateTime.Now.AddMinutes(2) - DateTime.Now), EventNames.OrderRelateCall, "123");
         //var times =await _expireTime.CalcExpiredTime(DateTime.Parse("2024-12-31 13:25:13.137977"), DateTime.Parse("2024-12-31 13:25:13.137977"), EFlowDirection.CenterToOrg,new OrderTimeClacInfo() { AcceptTypeCode= "10" });
         //await _expireTime.CalcWorkTimeToDecimal(visit.VisitTime.Value, DateTime.Now, false);
-        var times = await _expireTime.CalcWorkTimeToDecimal(DateTime.Parse("2024-12-16 21:36:27"), DateTime.Parse("2024-12-17 12:47:05"), false);
+        //var times = await _expireTime.CalcWorkTimeToDecimal(DateTime.Parse("2024-12-16 21:36:27"), DateTime.Parse("2024-12-17 12:47:05"), false);
+        var query = _userRepository.Queryable().Where(x => false);
         //await _capPublisher.PublishDelay(EventNames.OrderRelateCall, "123", cancellationToken: HttpContext.RequestAborted);
-        return OpenResponse.Ok(times);
+        return OpenResponse.Ok(query.ToSqlString());
     }
 
 

+ 2 - 6
src/Hotline.Api/Controllers/WebPortalController.cs

@@ -764,7 +764,7 @@ namespace Hotline.Api.Controllers
                            ConTypeName = p.HotspotName,
                            FlowAddDate = p.AcceptTime,
                            RSFlagName = p.State == "1" ? "办理完成" : "办理中",
-                           PubDate = p.PubDate
+                           PubDate = p.CreationTime
                        });
 
             var items = await _orderRepository.UnionAll(queryNew, queryold)
@@ -783,9 +783,6 @@ namespace Hotline.Api.Controllers
             return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(returnDto, "成功"));
         }
 
-        /// <summary>
-
-
         /// <summary>
         /// 查询工单发布后公开的数据
         /// </summary>
@@ -1373,8 +1370,7 @@ namespace Hotline.Api.Controllers
             var (total, items) = await _knowledgeRepository.Queryable()
                 .Where(p => p.IsPublic == true && p.Status == EKnowledgeStatus.OnShelf)
                 .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
-                // .WhereIF(!string.IsNullOrEmpty(typeSpliceNameTags), p => p.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceNameTags)))
-                .WhereIF(!string.IsNullOrEmpty(typeSpliceNameTags), p => p.Keywords.Contains(typeSpliceNameTags))
+                .WhereIF(!string.IsNullOrEmpty(typeSpliceNameTags), p => SqlFunc.JsonArrayAny(p.Keywords, typeSpliceNameTags) == true)
                 .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceName)))
                 .OrderByDescending(p => p.CreationTime)
                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

+ 3 - 0
src/Hotline.Api/Hotline.Api.csproj

@@ -35,6 +35,9 @@
     <None Update="Template\AssignmentForm.doc">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
+    <None Update="Template\QualityCertificate.doc">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
     <None Remove="logs\**" />
   </ItemGroup>
 

+ 2 - 2
src/Hotline.Application.Contracts/Validators/Order/AddOrderDtoValidator.cs

@@ -102,9 +102,9 @@ public class AddOrderDtoValidator : AbstractValidator<AddOrderDto>
         #endregion
 
         #region 投诉对象信息
-        RuleFor(d => d.OrderExtension.EnterpriseName).MaxLengthWithChineseChar(100).When(d => d.OrderExtension != null).WithMessage("企业名称最多100字符");
+        RuleFor(d => d.OrderExtension.EnterpriseName).MaxLengthWithChineseChar(80).When(d => d.OrderExtension != null).WithMessage("企业名称最多80字符");
         RuleFor(d => d.OrderExtension.UnifiedSocialCreditCode).MaxLengthWithChineseChar(30).When(d => d.OrderExtension != null).WithMessage("统一社会信用代码最多30字符");
-        RuleFor(d => d.OrderExtension.RegisterAddress).MaxLengthWithChineseChar(500).When(d => d.OrderExtension != null).WithMessage("企业注册地址最多500字符");
+        RuleFor(d => d.OrderExtension.RegisterAddress).MaxLengthWithChineseChar(400).When(d => d.OrderExtension != null).WithMessage("企业注册地址最多400字符");
         RuleFor(d => d.OrderExtension.RegisterNumber).MaxLengthWithChineseChar(50).When(d => d.OrderExtension != null).WithMessage("注册号最多50字符");
         RuleFor(d => d.OrderExtension.EnterpriseContact).MaxLengthWithChineseChar(70).When(d => d.OrderExtension != null).WithMessage("联系人最多70字符");
         RuleFor(d => d.OrderExtension.MarketTypeCode).MaxLengthWithChineseChar(64).When(d => d.OrderExtension != null).WithMessage("市场主体类型代码最多64字符");

+ 15 - 0
src/Hotline.Application.Tests/Application/RedPackApplicationTest.cs

@@ -51,6 +51,21 @@ public class RedPackApplicationTest : TestBase
             RedPackAuditId = audit.Id,
         };
         await _redPackApplication.AuditRedPackAuditAsync(inDto);
+        var suInDto = new UpdateRedPackRecordInDto
+        {
+            RedPackAuditId = audit.Id,
+            Name = "单元测试Name",
+            BankCardNo = "单元测试银行号",
+            OpenBank = "单元测试开户行",
+            ReplenishAmount = 100.01,
+            ReplenishTime = DateTime.Now,
+            ReplenishRemark = "单元测试补发备注",
+            IsSendSMS = false,
+            ReplenishType = "%15",
+            ReplenishTypeId = "1",
+        };
+        await _redPackApplication.UpdateRedPackRecordAsync(suInDto);
+
         items = await _redPackApplication.GetRedPackAuditItemsAsync(new SnapshotOrderAuditItemsInDto(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 1)).ToListAsync();
         items.Any(m => m.Id == audit.Id).ShouldBeTrue();
 

+ 52 - 0
src/Hotline.Application.Tests/Controller/OrderControllerTest.cs

@@ -18,6 +18,8 @@ using Hotline.Repository.SqlSugar;
 using Hotline.Repository.SqlSugar.Snapshot;
 using Hotline.Settings;
 using Hotline.Settings.Hotspots;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.File;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Order;
@@ -32,6 +34,7 @@ using Hotline.Share.Enums.Settings;
 using Hotline.Share.Tools;
 using Hotline.Snapshot.Interfaces;
 using Hotline.Users;
+using Mapster;
 using MediatR;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
@@ -60,6 +63,7 @@ public class OrderControllerTest : TestBase
     private readonly IRepository<OrderPublish> _orderPublishRepository;
     private readonly INotificationHandler<EndWorkflowNotify> _orderPublishEndWorkflowHandler;
     private readonly IOrderVisitRepository _orderVisitRepository;
+    private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
     private readonly IRepository<SystemSetting> _systemSettingRepository;
     private readonly ISystemSettingCacheManager _systemSettingCacheManager;
     private readonly IRepository<CallNative> _callNativeRepository;
@@ -68,6 +72,8 @@ public class OrderControllerTest : TestBase
     private readonly ISqlSugarClient _capSqlClient;
     private readonly IIndustryRepository _industryRepository;
     private readonly IOrderSnapshotRepository _orderSnapshotRepository;
+    private readonly ISystemLogRepository _systemLogRepository;
+    private readonly IOrderVisitDomainService _orderVisitDomainService;
 
     public OrderControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IRepository<Hotspot> hotspotRepository, OrderController orderController, IOrderRepository orderRepository, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, OrderServiceMock orderServiceMock, IRepository<OrderPublish> orderPublishRepository, INotificationHandler<EndWorkflowNotify> orderPublishEndWorkflowHandler, IOrderVisitRepository orderVisitRepository, IRepository<SystemSetting> systemSettingRepository, ISystemSettingCacheManager systemSettingCacheManager, IRepository<CallNative> callNativeRepository, IRepository<CallidRelation> callIdRelationRepository, XingTangCallApplication defaultCallApplication, ISugarUnitOfWork<CapDbContext> capDbContext, IHttpContextAccessor httpContextAccessor, IThirdIdentiyService thirdService, IThirdAccountRepository thirdAccount, IIndustryRepository industryRepository, IOrderSnapshotRepository orderSnapshotRepository) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository, httpContextAccessor, thirdService, thirdAccount)
     {
@@ -90,6 +96,9 @@ public class OrderControllerTest : TestBase
         _capSqlClient = capDbContext.Db;
         _industryRepository = industryRepository;
         _orderSnapshotRepository = orderSnapshotRepository;
+        _systemLogRepository = systemLogRepository;
+        _orderVisitDomainService = orderVisitDomainService;
+        _orderVisitDetailRepository = orderVisitDetailRepository;
     }
 
     /// <summary>
@@ -159,6 +168,49 @@ public class OrderControllerTest : TestBase
         }
     }
 
+    [Fact]
+    public async Task Visit_Test()
+    {
+        SetZuoXi();
+        var order = _orderServiceMock.CreateOrder()
+            .办理到一级部门()
+            .办理到二级部门(Set一级部门)
+            .办理一级部门汇总(Set二级部门)
+            .办理到归档(Set一级部门)
+            .发布工单(SetZuoXi)
+            .GetCreateResult();
+
+        var visit = await _orderVisitRepository.Queryable()
+            .Where(m => m.OrderId == order.Id)
+            .FirstAsync();
+        var visitDetaila = await _orderVisitDetailRepository.Queryable().Where(m => m.VisitId == visit.Id).ToListAsync();
+        var visitDetail = visitDetaila.Adapt<List<VisitDetailDto>>();
+        visitDetail.ForEach(m => { 
+            m.SeatEvaluate = ESeatEvaluate.DefaultSatisfied;
+            m.OrgProcessingResults = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<Kv>("0");
+            m.OrgHandledAttitude = _orderVisitDomainService.GetVisitEvaluateByReplyTxt<Kv>("0");
+        });
+
+        var callNo = DateTime.Now.ToString("yyyyMMddhhmmss") + "Flow";
+        var inDto = _fixture.Build<CallNative>()
+            .With(m => m.Id, Ulid.NewUlid().ToString())
+            .With(m => m.CallNo, callNo)
+            .With(m => m.Direction, ECallDirection.In)
+            .With(m => m.IsDeleted, false)
+            .Create();
+        await _callNativeRepository.AddAsync(inDto);
+
+        _systemLogRepository.Add("回访外呼已经接通", "", new CallRemarkDto { CallId = callNo,  CallNumber = inDto.ToNo }.ToJson(), "", 1, visit.Id);
+        var visitDto = new VisitDto
+        { 
+            Id = visit.Id,
+            IsPutThrough = true,
+            VisitDetails = visitDetail
+        };
+
+        await _orderController.Visit(visitDto);
+    }
+
     /// <summary>
     /// 创建工单并派送给派单员
     /// </summary>

+ 32 - 22
src/Hotline.Application/CallCenter/DefaultCallApplication.cs

@@ -333,28 +333,6 @@ public abstract class DefaultCallApplication : ICallApplication
         return callOrder.CallId;
     }
 
-    /// <summary>
-    /// 发送延迟消息让回访去关联通话记录
-    /// </summary>
-    /// <param name="cancellationToken"></param>
-    /// <returns></returns>
-    public virtual async Task PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken)
-    {
-        if (dto.CallId.IsNullOrEmpty()) return;
-
-        var seconds = _systemSettingCacheManager.VisitCallDelaySecond;
-        await _capPublisher.PublishDelayAsync(TimeSpan.FromSeconds(seconds), EventNames.VisitCallDelay, dto, cancellationToken: cancellationToken);
-    }
-
-    public virtual async Task PublishOrderRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken)
-    {
-        if (dto.CallId.IsNullOrEmpty()) return;
-
-        var seconds = _systemSettingCacheManager.VisitCallDelaySecond;
-        await _capPublisher.PublishDelayAsync(TimeSpan.FromSeconds(seconds), EventNames.VisitCallDelay, dto, cancellationToken: cancellationToken);
-    }
-
-
     public async Task<CallidRelation> GetRelationAsync(string callNo, CancellationToken cancellation)
     {
         return await _callIdRelationRepository.GetAsync(callNo, cancellation);
@@ -468,6 +446,38 @@ public abstract class DefaultCallApplication : ICallApplication
     }
 
     /// <summary>
+    /// 发送延迟消息让回访去关联通话记录
+    /// 如果前端入参中的CallId为空, 就根据回访Id在systemLog中查询.前端在回访界面点击"回访"按钮拨号时会在systemLog中保存回访的号码,callNo,回访Id;
+    /// 通过systemLog修复前端没有传callId这种情况;
+    /// </summary>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public virtual async Task<string> PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken)
+    {
+        if (dto.CallId.IsNullOrEmpty())
+        {
+            try
+            {
+                var log = await _systemLogRepository.Queryable()
+                    .Where(m => m.IpUrl == dto.Id && m.Name == "回访外呼已经接通")
+                    .FirstAsync(cancellationToken);
+                if (log is null || log.Remark.IsNullOrEmpty()) return null;
+                var callRemark = log.Remark.FromJson<CallRemarkDto>();
+                dto.CallId = callRemark.CallId;
+            }
+            catch (Exception e)
+            { 
+                _logger.LogError($"PublishVisitRelevanceCallIdAsync: {e.ToJson()}");
+            }
+        }
+
+        var seconds = _systemSettingCacheManager.VisitCallDelaySecond;
+        await _capPublisher.PublishDelayAsync(TimeSpan.FromSeconds(seconds), EventNames.VisitCallDelay, dto, cancellationToken: cancellationToken);
+        return dto.CallId;
+    }
+
+    /// <summary>
+    /// 处理: EventNames.VisitCallDelay 消息
     /// 保存回访详情时发送延迟消息同步通话记录
     /// 如果回访通话记录有多条, 需要关联通话时长最长的那条
     /// </summary>

+ 1 - 1
src/Hotline.Application/CallCenter/ICallApplication.cs

@@ -84,7 +84,7 @@ namespace Hotline.Application.CallCenter
         /// </summary>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken);
+        Task<string> PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken);
 
         Task<CallidRelation> GetRelationAsync(string callNo, CancellationToken cancellation);
 

+ 2 - 2
src/Hotline.Application/CallCenter/TianRunCallApplication.cs

@@ -109,9 +109,9 @@ namespace Hotline.Application.CallCenter
             return await Task.FromResult(callNo);
         }
 
-        public override async Task PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken)
+        public override async Task<string> PublishVisitRelevanceCallIdAsync(OrderRelevanceCallIdDto dto, CancellationToken cancellationToken)
         {
-            return;
+            return null;
         }
 
         public override async Task OrderVisitRelevanceCallIdAsync(VisitDto dto, CancellationToken cancellationToken)

+ 25 - 4
src/Hotline.Application/Orders/OrderApplication.cs

@@ -100,8 +100,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
     private readonly IRepository<StatisticsDepartSatisfied> _statisticsDepartSatisfiedRepository;
     private readonly IRepository<OrderTsDetails> _orderTsDetailsRepository;
     private readonly IRepository<KnowledgeQuote> _knowledgeQuoteRepository;
+	private readonly IRepository<OrderSpecial> _orderSpecialRepository;
 
-    public OrderApplication(
+	public OrderApplication(
         IOrderDomainService orderDomainService,
         IOrderRepository orderRepository,
         IWorkflowDomainService workflowDomainService,
@@ -143,7 +144,8 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         IRepository<StatisticsDepartSatisfied> statisticsDepartSatisfiedRepository,
         IOrderDelayRepository orderDelayRepository,
         IRepository<OrderTsDetails> orderTsDetailsRepository,
-        IRepository<KnowledgeQuote> knowledgeQuoteRepository)
+        IRepository<KnowledgeQuote> knowledgeQuoteRepository,
+		IRepository<OrderSpecial> orderSpecialRepository)
     {
         _orderDomainService = orderDomainService;
         _workflowDomainService = workflowDomainService;
@@ -187,7 +189,9 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         _statisticsDepartSatisfiedRepository = statisticsDepartSatisfiedRepository;
         _orderTsDetailsRepository = orderTsDetailsRepository;
         _knowledgeQuoteRepository = knowledgeQuoteRepository;
-    }
+        _orderSpecialRepository = orderSpecialRepository;
+
+	}
 
     /// <summary>
     /// 更新工单办理期满时间(延期调用,其他不调用)
@@ -784,6 +788,12 @@ public class OrderApplication : IOrderApplication, IScopeDependency
               .WhereIF(dto.IsOverTime == false,
                   d => (d.ExpiredTime > DateTime.Now && d.Status < EOrderStatus.Filed) ||
                        (d.ExpiredTime > d.ActualHandleTime && d.Status >= EOrderStatus.Filed))//否 超期
+              .WhereIF(!string.IsNullOrEmpty(dto.ProvinceChannel) && dto.ProvinceChannel == "1", d => d.Source == ESource.ProvinceStraight &&
+                 d.SourceChannelCode == "SZMHD" && d.IsProvince == false) //政民互动直派
+             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceChannel) && dto.ProvinceChannel == "2", d => d.Source == ESource.ProvinceStraight &&
+                 d.SourceChannelCode == "SZMHD" && d.IsProvince == true) //政民互动
+             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceChannel) && dto.ProvinceChannel == "3", d => d.Source == ESource.ProvinceStraight &&
+                 d.SourceChannelCode == "S12345" && d.IsProvince == true) //省12345
               .OrderByDescending(d => d.FiledTime);
     }
 
@@ -815,6 +825,12 @@ public class OrderApplication : IOrderApplication, IScopeDependency
             .WhereIF(dto.IsOverTime == false,
                 d => (d.Order.ExpiredTime > DateTime.Now && d.Order.Status < EOrderStatus.Filed) ||
                      (d.Order.ExpiredTime > d.Order.ActualHandleTime && d.Order.Status >= EOrderStatus.Filed)) //否 超期
+             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceChannel) && dto.ProvinceChannel == "1", d => d.Order.Source == ESource.ProvinceStraight &&
+                 d.Order.SourceChannelCode == "SZMHD" && d.Order.IsProvince == false) //政民互动直派
+             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceChannel) && dto.ProvinceChannel == "2", d => d.Order.Source == ESource.ProvinceStraight &&
+                 d.Order.SourceChannelCode == "SZMHD" && d.Order.IsProvince == true) //政民互动
+             .WhereIF(!string.IsNullOrEmpty(dto.ProvinceChannel) && dto.ProvinceChannel == "3", d => d.Order.Source == ESource.ProvinceStraight &&
+                 d.Order.SourceChannelCode == "S12345" && d.Order.IsProvince == true) //省12345
             .OrderByDescending(d => d.CreationTime);
     }
 
@@ -999,8 +1015,13 @@ public class OrderApplication : IOrderApplication, IScopeDependency
         {
             throw UserFriendlyException.SameMessage("该工单存在正在审核中的退回,不能办理");
         }
+		if (await _orderSpecialRepository.AnyAsync(x => x.OrderId == order.Id && x.State == 0,
+		   cancellationToken))
+		{
+			throw UserFriendlyException.SameMessage("该工单存在正在审核中的特提,不能办理");
+		}
 
-        ExpiredTimeWithConfig? expiredTimeConfig = null;
+		ExpiredTimeWithConfig? expiredTimeConfig = null;
         var settingBase = _systemSettingCacheManager.GetSetting(SettingConstants.CityBaseConfiguration)?.SettingValue[0];
         CityBaseConfiguration cityBase = System.Text.Json.JsonSerializer.Deserialize<CityBaseConfiguration>(settingBase);
         if (dto.Workflow.NextHandlers.Any(d => d.Key == cityBase.CityProvince.OrgId || d.Key == cityBase.CityProvinceAssign.OrgId))

+ 11 - 1
src/Hotline.Application/Snapshot/IOrderSnapshotApplication.cs

@@ -2,6 +2,7 @@
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Order;
 using Hotline.Share.Dtos.Snapshot;
+using Hotline.Snapshot;
 using SqlSugar;
 using System;
 using System.Collections.Generic;
@@ -60,7 +61,7 @@ public interface IOrderSnapshotApplication
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    ISugarQueryable<LabelOrderSnapshotItemsOutDto> GetLabelOrderSnapshotItemsAsync(LabelOrderSnapshotItemsInDto dto);
+    ISugarQueryable<SignOrderSnapshotItemsOutDto> GetSignOrderSnapshotItemsAsync(SignOrderSnapshotItemsInDto dto);
 
     /// <summary>
     /// 批量设置随手拍公开申请不通过
@@ -117,4 +118,13 @@ public interface IOrderSnapshotApplication
     /// <param name="dto"></param>
     /// <returns></returns>
     ISugarQueryable<LabeledOrderSnapshotItemsOutDto> GetLabeledOrderSnapshotItemsAsync(LabeledOrderSnapshotItemsInDto dto);
+
+    /// <summary>
+    /// 工单标记
+    /// </summary>
+    /// <param name="orderId"></param>
+    /// <param name="isSafetyDepartment"></param>
+    /// <param name="remark"></param>
+    /// <returns></returns>
+    Task<OrderSnapshot> UpdateSafetyAsync(string orderId, bool isSafetyDepartment, string remark);
 }

+ 3 - 1
src/Hotline.Application/Snapshot/IRedPackApplication.cs

@@ -1,4 +1,5 @@
-using Hotline.Share.Dtos.Snapshot;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Snapshot;
 using SqlSugar;
 using System;
 using System.Collections.Generic;
@@ -83,6 +84,7 @@ public interface IRedPackApplication
     /// <param name="dto"></param>
     /// <returns></returns>
     ISugarQueryable<SnapshotRedPackRecordItemsOutDto> GetRedPackRecordItemsAsync(SnapshotRedPackRecordItemsInDto dto);
+    ISugarQueryable<SnapshotRedPackRecordSupplementItemsOutDto> GetRedPackRecordSupplementItemsAsync(SnapshotRedPackRecordSupplementItemsInDto dto);
 
     /// <summary>
     /// 审核添加备注

+ 17 - 6
src/Hotline.Application/Snapshot/OrderSnapshotApplication.cs

@@ -42,8 +42,9 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
     private readonly IIndustryRepository _industryRepository;
     private readonly IFileRepository _fileRepository;
     private readonly ISnapshotLabelLogRepository _snapshotLabelLogRepository;
+    private readonly IRedPackAuditRepository _redPackAuditRepository;
 
-    public OrderSnapshotApplication(IOrderSnapshotRepository orderSnapshotRepository, IOrderRepository orderRepository, ISnapshotOrderPublishRepository snapshotOrderPublishRepository, ISessionContext sessionContext, ISystemSettingCacheManager systemSettingCacheManager, IIndustryCaseRepository industryCaseRepository, ISystemDicDataCacheManager systemDicDataCacheManager, IIndustryRepository industryRepository, IFileRepository fileRepository, ISnapshotLabelLogRepository snapshotLabelLogRepository)
+    public OrderSnapshotApplication(IOrderSnapshotRepository orderSnapshotRepository, IOrderRepository orderRepository, ISnapshotOrderPublishRepository snapshotOrderPublishRepository, ISessionContext sessionContext, ISystemSettingCacheManager systemSettingCacheManager, IIndustryCaseRepository industryCaseRepository, ISystemDicDataCacheManager systemDicDataCacheManager, IIndustryRepository industryRepository, IFileRepository fileRepository, ISnapshotLabelLogRepository snapshotLabelLogRepository, IRedPackAuditRepository redPackAuditRepository)
     {
         _orderSnapshotRepository = orderSnapshotRepository;
         _orderRepository = orderRepository;
@@ -55,6 +56,7 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
         _industryRepository = industryRepository;
         _fileRepository = fileRepository;
         _snapshotLabelLogRepository = snapshotLabelLogRepository;
+        _redPackAuditRepository = redPackAuditRepository;
     }
 
     /// <summary>
@@ -198,7 +200,7 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
     /// </summary>
     /// <param name="dto"></param>
     /// <returns></returns>
-    public ISugarQueryable<LabelOrderSnapshotItemsOutDto> GetLabelOrderSnapshotItemsAsync(LabelOrderSnapshotItemsInDto dto)
+    public ISugarQueryable<SignOrderSnapshotItemsOutDto> GetSignOrderSnapshotItemsAsync(SignOrderSnapshotItemsInDto dto)
     {
         var query = _orderSnapshotRepository.Queryable()
             .LeftJoin<Order>((snapshot, order) => snapshot.Id == order.Id)
@@ -209,7 +211,7 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
             .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)
-            .Select((snapshot, order) => new LabelOrderSnapshotItemsOutDto
+            .Select((snapshot, order) => new SignOrderSnapshotItemsOutDto
             {
                 OrderId = snapshot.Id,
                 No = order.No,
@@ -222,8 +224,8 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
                 NetworkENumber = snapshot.NetworkENumber,
                 NetworkRemark = snapshot.NetworkRemark,
                 ReplyDate = snapshot.ReplyDate,
-                LabelTime = snapshot.LabelTime,
-                LabelUserName = snapshot.LabelUserName
+                LabelTime = snapshot.SignTime,
+                LabelUserName = snapshot.SignUserName
             });
         return query;
     }
@@ -319,7 +321,7 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
             snapshot.IsRectifyDepartment = dto.Data.IsRectifyDepartment.Value;
             snapshot.IndustryCase = dto.Data.IndustryCase;
             snapshot.IsAward = dto.Data.IsAward;
-            snapshot.AwardOpenBack = dto.Data.AwardOpenBack;
+            snapshot.AwardOpenBank = dto.Data.AwardOpenBank;
             snapshot.AwardName = dto.Data.AwardName;
             snapshot.AwardBankCardNo = dto.Data.AwardBankCardNo;
             snapshot.ReplenishTypeId = dto.Data.ReplenishTypeId;
@@ -466,4 +468,13 @@ public class OrderSnapshotApplication : IOrderSnapshotApplication, IScopeDepende
         return query;
     }
 
+    public async Task<OrderSnapshot> UpdateSafetyAsync(string orderId, bool isSafetyDepartment, string remark)
+    {
+        // 红包已经审核通过的工单不允许修改
+        if (await _redPackAuditRepository.Queryable().AnyAsync(m => m.OrderId == orderId && m.Status == ERedPackAuditStatus.Agree))
+        {
+            return await _orderSnapshotRepository.GetAsync(orderId);
+        }
+        return await _orderSnapshotRepository.UpdateSafetyAsync(orderId, isSafetyDepartment, remark);
+    }
 }

+ 34 - 7
src/Hotline.Application/Snapshot/RedPackApplication.cs

@@ -1,4 +1,5 @@
 using Hotline.Orders;
+using Hotline.Share.Dtos;
 using Hotline.Share.Dtos.Snapshot;
 using Hotline.Share.Enums.Order;
 using Hotline.Share.Enums.Snapshot;
@@ -27,8 +28,9 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
     private readonly ISessionContext _sessionContext;
     private readonly IRedPackGuiderAuditRepository _redPackGuiderAuditRepository;
     private readonly IThirdAccountRepository _thirdAccountRepository;
+    private readonly ISupplementRecordRepository _supplementRecordRepository;
 
-    public RedPackApplication(IOrderSnapshotRepository orderSnapshotRepository, ISnapshotSMSTemplateRepository snapshotSMSTemplateRepository, IOrderRepository orderRepository, IIndustryRepository industryRepository, IRedPackAuditRepository redPackAuditRepository, IRedPackRecordRepository redPackRecordRepository, IRepository<OrderSpecial> orderSpecialRepository, ISessionContext sessionContext, IRedPackGuiderAuditRepository redPackGuiderAuditRepository, IThirdAccountRepository thirdAccountRepository)
+    public RedPackApplication(IOrderSnapshotRepository orderSnapshotRepository, ISnapshotSMSTemplateRepository snapshotSMSTemplateRepository, IOrderRepository orderRepository, IIndustryRepository industryRepository, IRedPackAuditRepository redPackAuditRepository, IRedPackRecordRepository redPackRecordRepository, IRepository<OrderSpecial> orderSpecialRepository, ISessionContext sessionContext, IRedPackGuiderAuditRepository redPackGuiderAuditRepository, IThirdAccountRepository thirdAccountRepository, ISupplementRecordRepository supplementRecordRepository)
     {
         _orderSnapshotRepository = orderSnapshotRepository;
         _snapshotSMSTemplateRepository = snapshotSMSTemplateRepository;
@@ -40,6 +42,7 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
         _sessionContext = sessionContext;
         _redPackGuiderAuditRepository = redPackGuiderAuditRepository;
         _thirdAccountRepository = thirdAccountRepository;
+        _supplementRecordRepository = supplementRecordRepository;
     }
 
     /// <summary>
@@ -156,13 +159,14 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
         if (count != 0)
             outDto.RedPackTxt += $"今天审批【{count}】个";
 
-        outDto.AuditComBox = EnumExts.GetDescriptions<ESnapshotSMSStatus>();
+        outDto.AuditComBox = EnumExts.GetDescriptions<ERedPackAuditStatus>()
+            .Where(m => m.Key.ToString() != "0").ToList(); ;
         return outDto;
     }
 
 
     /// <summary>
-    /// 获取审核详情
+    /// 获取市民审核详情
     /// </summary>
     /// <param name="id">工单Id</param>
     /// <returns></returns>
@@ -211,7 +215,7 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
             .LeftJoin<OrderSnapshot>((redPackAudit, order, snapshot) => redPackAudit.OrderId == snapshot.Id)
             .LeftJoin<RedPackRecord>((redPackAudit, order, snapshot, record) => redPackAudit.Id == record.OrderId)
             .LeftJoin<Industry>((redPackAudit, order, snapshot, record, industry) => snapshot.IndustryId == industry.Id)
-            .Where((redPackAudit, order, snapshot, record, industry) => order.Status == EOrderStatus.Filed)
+            .Where((redPackAudit, order, snapshot, record, industry) => order.Status >= EOrderStatus.Filed)
             .WhereIF(dto.No.NotNullOrEmpty(), (redPackAudit, order, snapshot, record, industry) => order.No.Contains(dto.No))
             .WhereIF(dto.Title.NotNullOrEmpty(), (redPackAudit, order, snapshot, record, industry) => order.Title.Contains(dto.Title))
             .WhereIF(dto.FromPhone.NotNullOrEmpty(), (redPackAudit, order, snapshot, record, industry) => order.FromPhone.Contains(dto.FromPhone))
@@ -393,12 +397,22 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
             .FirstAsync() ?? throw UserFriendlyException.SameMessage("审核记录不存在");
         var audit = await _redPackAuditRepository.GetAsync(dto.RedPackAuditId) ?? throw UserFriendlyException.SameMessage("审核记录不存在");
 
-        dto.Adapt(record);
-        await _redPackRecordRepository.UpdateAsync(record);
-
         dto.Adapt(audit);
         await _redPackAuditRepository.UpdateAsync(audit);
 
+        var entity = dto.Adapt<SupplementRecord>();
+        var industryName = await _orderSnapshotRepository.Queryable()
+            .Where(m => m.Id == record.OrderId)
+            .Select(m => new { m.IndustryName, m.IndustryId })
+            .FirstAsync();
+        entity.OrderId = record.OrderId;
+        entity.RedPackRecordId = record.Id;
+        entity.RedPackAuditId = audit.Id;
+        entity.No = record.No;
+        entity.IndustryName = industryName.IndustryName;
+        entity.IndustryId = industryName.IndustryId;
+        await _supplementRecordRepository.AddAsync(entity);
+
         if (dto.IsSendSMS)
         {
             // TODO: 发送短信
@@ -494,6 +508,19 @@ public class RedPackApplication : IRedPackApplication, IScopeDependency
         return query;
     }
 
+    public ISugarQueryable<SnapshotRedPackRecordSupplementItemsOutDto> GetRedPackRecordSupplementItemsAsync(SnapshotRedPackRecordSupplementItemsInDto dto)
+    {
+        var query = _supplementRecordRepository.Queryable()
+            .LeftJoin<Order>((supp, order) => supp.OrderId == order.Id)
+            .WhereIF(dto.No.NotNullOrEmpty(), (supp, order) => order.No.Contains(dto.No))
+            .WhereIF(dto.FromPhone.NotNullOrEmpty(), (supp, order) => order.FromPhone.Contains(dto.FromPhone))
+            .WhereIF(dto.Title.NotNullOrEmpty(), (supp, order) => order.Title.Contains(dto.Title))
+            .WhereIF(dto.IndustryId.NotNullOrEmpty(), (supp, order) => supp.IndustryId == dto.IndustryId)
+            .WhereIF(dto.BeginCreationTime.HasValue && dto.EndCreationTime.HasValue, (supp, order) => supp.CreationTime >= dto.BeginCreationTime && supp.CreationTime <= dto.EndCreationTime)
+            .Select<SnapshotRedPackRecordSupplementItemsOutDto>();
+        return query;
+    }
+
 
     #endregion
 }

+ 9 - 4
src/Hotline.Application/Snapshot/SnapshotApplicationBase.cs

@@ -202,6 +202,11 @@ public abstract class SnapshotApplicationBase
         if (indurstry.IndustryType == EIndustryType.Declare)
         {
             outDto.AreaTree = (await _systemAreaDomainService.GetAreaTree(parentId: "510300")).Adapt<List<SystemAreaOutDto>>();
+            outDto.AreaTree.ToList().ForEach(m => 
+            {
+                if (m.Children.IsNullOrEmpty())
+                    m.Children = new List<SystemAreaOutDto>() { new SystemAreaOutDto { Id = "0",  AreaName = "无"} };
+            });
             outDto.Files = (await _fileRepository.GetByKeyAsync(indurstry.Id, requestAborted)).Adapt<List<IndustryFileDto>>();
             outDto.Files.ToList().ForEach(m => m.Url = fileDownloadApi + m.AdditionId);
             outDto.WorkplaceName = _systemDicDataCacheManager.WorkplaceName;
@@ -523,22 +528,22 @@ public abstract class SnapshotApplicationBase
         dto.ValidateObject();
         if (int.TryParse(dto.InvitationCode, out var invitationCode) == false)
         { 
-            throw UserFriendlyException.SameMessage("邀请码格式错误");
+            throw new UserFriendlyException(200, "邀请码格式错误");
         }
         var third = await _thirdAccountRepository.GetByOpenIdAsync(_sessionContext.OpenId)
             ?? throw UserFriendlyException.SameMessage("用户不存在");
         if (third.InvitationCode.NotNullOrEmpty())
         {
-            throw UserFriendlyException.SameMessage("邀请码已存在");
+            throw new UserFriendlyException(200, "邀请码已存在");
         }
         if (_inviteCodeRecordRepository.Queryable().Where(m => m.InviteCode == dto.InvitationCode).Any())
         {
-            throw UserFriendlyException.SameMessage("邀请码已经被使用");
+            throw new UserFriendlyException(200, "邀请码已经被使用");
         }
         third.InvitationCode = dto.InvitationCode;
         var invite = await _inviteCodeRepository.Queryable()
             .Where(m => invitationCode >= m.BeginCode && invitationCode <= m.EndCode)
-            .FirstAsync() ?? throw UserFriendlyException.SameMessage("邀请码无效");
+            .FirstAsync() ?? throw new UserFriendlyException(200, "邀请码无效");
         var entity = new InviteCodeRecord
         {
             OrgId = invite.Id,

+ 1 - 1
src/Hotline.Application/StatisticalReport/OrderReportApplication.cs

@@ -1613,7 +1613,7 @@ namespace Hotline.Application.StatisticalReport
                     NoPassTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)),
                     ExaminingTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0)),
                     WithdrawTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Withdraw,1,0)),
-                    AllTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0))
+                    //AllTotal = SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Pass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.NoPass, 1, 0)) + SqlFunc.AggregateSum(SqlFunc.IIF(x.DelayState == EDelayState.Examining, 1, 0))
 
                 }).MergeTable();
 

+ 1 - 1
src/Hotline.Repository.SqlSugar/CallCenter/TrCallRecordRepository.cs

@@ -385,7 +385,7 @@ namespace Hotline.Repository.SqlSugar.CallCenter
                     EnterpriseCallOutPutthroughCount = a.EnterpriseCallOutPutthroughCount,
                     AiVisitCallOutPutthroughCount = b.AiVisitCallOutPutthroughCount,
                     AiCallOutPutthroughCount = 0,
-                }).OrderBy(x=>x.Date).ToListAsync();
+                }).OrderBy(a=>a.Date).ToListAsync();
             return list;
         }
 

+ 19 - 14
src/Hotline.Repository.SqlSugar/Orders/OrderRepository.cs

@@ -830,11 +830,11 @@ namespace Hotline.Repository.SqlSugar.Orders
                 {
                     AllCount = x.AllCount,
                     // 回访情况
-                    SatisfactionRate = SqlFunc.Round((decimal)(x.AllCount - x.SatisfactionCount) * 100 / (decimal)x.AllCount, 2),                     //总体满意率
-                    DepartSatisfactionRate = SqlFunc.Round((decimal)(x.DepartCount - x.DepartSatisfactionCount) * 100 / (decimal)x.DepartCount, 2),   //部门满意率
-                    CenterSatisfactionRate = SqlFunc.Round((decimal)(x.CenterCount - x.CenterSatisfactionCount) * 100 / (decimal)x.CenterCount, 2),   //12345中心满意率
-                    CitySatisfactionRate = SqlFunc.Round((decimal)(x.CityCount - x.CitySatisfactionCount) * 100 / (decimal)x.CityCount, 2),           //市级部门满意率
-                    CountySatisfactionRate = SqlFunc.Round((decimal)(x.CountyCount - x.CountySatisfactionCount) * 100 / (decimal)x.CountyCount, 2),   //县(区)满意率
+                    SatisfactionRate = x.AllCount > 0 ? SqlFunc.Round((decimal)(x.AllCount - x.SatisfactionCount) * 100 / (decimal)x.AllCount, 2):0,                     //总体满意率
+                    DepartSatisfactionRate = x.DepartCount > 0 ? SqlFunc.Round((decimal)(x.DepartCount - x.DepartSatisfactionCount) * 100 / (decimal)x.DepartCount, 2) : 0,   //部门满意率
+                    CenterSatisfactionRate = x.CenterCount > 0 ? SqlFunc.Round((decimal)(x.CenterCount - x.CenterSatisfactionCount) * 100 / (decimal)x.CenterCount, 2) : 0,   //12345中心满意率
+                    CitySatisfactionRate = x.CityCount > 0 ? SqlFunc.Round((decimal)(x.CityCount - x.CitySatisfactionCount) * 100 / (decimal)x.CityCount, 2) : 0,           //市级部门满意率
+                    CountySatisfactionRate = x.CountyCount > 0 ? SqlFunc.Round((decimal)(x.CountyCount - x.CountySatisfactionCount) * 100 / (decimal)x.CountyCount, 2) : 0,   //县(区)满意率
                     SatisfactionCount = x.SatisfactionCount,                                                                                          //不满意件
                     CenterSatisfactionCount = x.CenterSatisfactionCount,                                                                              //市级部门不满意件
                     CountySatisfactionCount = x.CountySatisfactionCount,
@@ -846,7 +846,7 @@ namespace Hotline.Repository.SqlSugar.Orders
                     OrderAllCount = x.OrderAllCount,                                                                    // 来件总数
                     OrderAlready = x.OrderAlready,                                                                      // 已办件数
                     OrderWait = x.OrderWait,                                                                            // 在办件数
-                    OrderAlreadyRate = SqlFunc.Round((decimal)(x.OrderAlready) * 100 / (decimal)x.OrderAllCount, 2),    //总体办结率
+                    OrderAlreadyRate = x.OrderAllCount > 0 ? SqlFunc.Round((decimal)(x.OrderAlready) * 100 / (decimal)x.OrderAllCount, 2):0,    //总体办结率
                     OrderCityCount = x.OrderCityCount,                                                                  //市级部门受理
                     OrderCountyCount = x.OrderCountyCount,                                                              //县(区)受理
                     OrderCenterCount = x.OrderCenterCount,                                                              //12345中心受理
@@ -874,25 +874,25 @@ namespace Hotline.Repository.SqlSugar.Orders
                     CityWorkTime = x.CityWorkTime,
                     CountyWorkTime = x.CountyWorkTime,
                     CenterWorkTime = x.CenterWorkTime,
-                    OrderWorkTimeRate = SqlFunc.Round((decimal)(x.OrderWorkTime) / (decimal)x.OrderAlready / 60 / 8, 2),          //信件办理平均时长(工作日)
-                    CityWorkTimeRate = SqlFunc.Round((decimal)(x.CityWorkTime) / (decimal)x.CityAlready / 60 / 8, 2),             //市级部门平均时长(工作日)
-                    CountyWorkTimeRate = SqlFunc.Round((decimal)(x.CountyWorkTime) / (decimal)x.CountyAlready / 60 / 8, 2),       //县(区)平均时长(工作日)
-                    CenterWorkTimeRate = SqlFunc.Round((decimal)(x.CenterWorkTime) / (decimal)x.CenterAlready / 60 / 8, 2),        //12345中心平均时长(工作日)
+                    OrderWorkTimeRate = x.OrderAlready > 0 ? SqlFunc.Round((decimal)(x.OrderWorkTime) / (decimal)x.OrderAlready / 60 / 8, 2) : 0,          //信件办理平均时长(工作日)
+                    CityWorkTimeRate = x.CityAlready > 0 ? SqlFunc.Round((decimal)(x.CityWorkTime) / (decimal)x.CityAlready / 60 / 8, 2) : 0,             //市级部门平均时长(工作日)
+                    CountyWorkTimeRate = x.CountyAlready > 0 ? SqlFunc.Round((decimal)(x.CountyWorkTime) / (decimal)x.CountyAlready / 60 / 8, 2) : 0,       //县(区)平均时长(工作日)
+                    CenterWorkTimeRate = x.CenterAlready > 0 ? SqlFunc.Round((decimal)(x.CenterWorkTime) / (decimal)x.CenterAlready / 60 / 8, 2) : 0,        //12345中心平均时长(工作日)
 
                     // 企业服务办件情况
                     EnterpriseAllCount = x.EnterpriseAllCount,
                     EnterpriseAlready = x.EnterpriseAlready,                                                                                            //已办信件
                     EnterpriseWait = x.EnterpriseWait,                                                                                                  //在办信件
                     EnterpriseVisit = x.EnterpriseVisit,                                                                                                //回访总量
-                    EnterpriseSatisfactionRate = SqlFunc.Round((decimal)(x.EnterpriseSatisfaction) * 100 / (decimal)x.EnterpriseVisit, 2),              //总满意率
+                    EnterpriseSatisfactionRate = x.EnterpriseVisit > 0 ? SqlFunc.Round((decimal)(x.EnterpriseSatisfaction) * 100 / (decimal)x.EnterpriseVisit, 2) : 0,              //总满意率
                     EnterpriseCenter = x.EnterpriseCenter,                                                                                              //12345直办件
                     EnterpriseCity = x.EnterpriseCity,                                                                                                  //市级部门办件
                     EnterpriseCounty = x.EnterpriseCounty,                                                                                              //县(区)办件
                     EnterpriseDisSatisfaction = x.EnterpriseVisit - x.EnterpriseSatisfaction,                                                           //不满意信件总量
                     EnterpriseCitySatisfaction = x.EnterpriseCitySatisfaction,
-                    EnterpriseCitySatisfactionRate = SqlFunc.Round((decimal)(x.EnterpriseCitySatisfaction) * 100 / (decimal)x.EnterpriseCity, 2),       //市级部门满意率
+                    EnterpriseCitySatisfactionRate = x.EnterpriseCity > 0 ? SqlFunc.Round((decimal)(x.EnterpriseCitySatisfaction) * 100 / (decimal)x.EnterpriseCity, 2) : 0,       //市级部门满意率
                     EnterpriseCountySatisfaction = x.EnterpriseCountySatisfaction,
-                    EnterpriseCountySatisfactionRate = SqlFunc.Round((decimal)(x.EnterpriseCountySatisfaction) * 100 / (decimal)x.EnterpriseCounty, 2), //县(区)满意率
+                    EnterpriseCountySatisfactionRate = x.EnterpriseCounty > 0 ? SqlFunc.Round((decimal)(x.EnterpriseCountySatisfaction) * 100 / (decimal)x.EnterpriseCounty, 2) : 0, //县(区)满意率
                     EnterpriseWorkTime = x.EnterpriseWorkTime,
                     EnterpriseCityWorkTime = x.EnterpriseCityWorkTime,
                     EnterpriseCountyWorkTime = x.EnterpriseCountyWorkTime,
@@ -980,7 +980,12 @@ namespace Hotline.Repository.SqlSugar.Orders
                   p.count
               })
                .ToPivotTableAsync(p => p.DicDataName, p => p.Hour, p => p.Sum(x => x.count));
-            var dtList = list.Clone();
+			var col1 = list.Columns.Contains("Column1");
+			if (col1)
+			{
+				list.Columns.Remove("Column1");
+			}
+			var dtList = list.Clone();
 
             if (await Db.Queryable<StatisticsPurTypeSatisfied>().Where(x => x.Time >= dto.StartTime && x.Time <= dto.EndTime).AnyAsync())
             {

+ 9 - 0
src/Hotline.Repository.SqlSugar/Snapshot/IndustryRepository.cs

@@ -17,6 +17,15 @@ public class IndustryRepository : BaseRepository<Industry>, IIndustryRepository,
     {
     }
 
+    public async Task<IList<dynamic>> GetDataBaseAsync()
+    {
+        var result = await Queryable()
+            .Select(m => new { m.Id, m.Name })
+            .ToListAsync();
+
+        return result.Cast<dynamic>().ToList();
+    }
+
     public async Task<double> GetIntervalTimeAsync(string industryId, double defaultValue,  CancellationToken cancellationToken)
     {
         var time = await Queryable().Where(m => m.Id == industryId).Select(m => m.IntervalTime).FirstAsync(cancellationToken);

+ 18 - 0
src/Hotline.Repository.SqlSugar/Snapshot/SupplementRecordRepository.cs

@@ -0,0 +1,18 @@
+using Hotline.Repository.SqlSugar.DataPermissions;
+using Hotline.Snapshot;
+using Hotline.Snapshot.Interfaces;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Dependency;
+
+namespace Hotline.Repository.SqlSugar.Snapshot;
+public class SupplementRecordRepository : BaseRepository<SupplementRecord>, ISupplementRecordRepository, IScopeDependency
+{
+    public SupplementRecordRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder) : base(uow, dataPermissionFilterBuilder)
+    {
+    }
+}

+ 1 - 1
src/Hotline.Share/Dtos/CallCenter/BiQueryCallsDto.cs

@@ -289,7 +289,7 @@ public class QueryCallDateStatisticsDetailResp
     /// <summary>
     /// 服务接通率
     /// </summary>
-    public double ServicePutthorughRate => (PersonCallInPutthroughCount + EnterpriseCallInPutthroughCount + AiCallInPutthroughCount) == 0 ? 0 : Math.Round(((double)PutthroughCount / (PersonCallInPutthroughCount + EnterpriseCallInPutthroughCount + AiCallInPutthroughCount)) * 100, 2);
+    public double ServicePutthorughRate => (PersonCallInCount + EnterpriseCallInCount + AiCallInCount) == 0 ? 0 : Math.Round(((double)PutthroughCount / (PersonCallInCount + EnterpriseCallInCount + AiCallInCount)) * 100, 2);
 
     /// <summary>
     /// 服务接通率(文本)

+ 13 - 0
src/Hotline.Share/Dtos/CallCenter/CallDto.cs

@@ -179,4 +179,17 @@ namespace Hotline.Share.Dtos.CallCenter
         /// </summary>
         public string CallId { get; set; }
     }
+
+    public class CallRemarkDto
+    {
+        /// <summary>
+        /// 电话号码
+        /// </summary>
+        public string CallNumber { get; set; }
+
+        /// <summary>
+        /// CallNo
+        /// </summary>
+        public string CallId { get; set; }
+    }
 }

+ 1 - 1
src/Hotline.Share/Dtos/Order/OrderBiDto.cs

@@ -199,7 +199,7 @@ namespace Hotline.Share.Dtos.Order
         /// <summary>
         /// 小计
         /// </summary>
-        public int AllTotal { get; set; }
+        public int AllTotal => PassTotal + NoPassTotal + ExaminingTotal + WithdrawTotal;
         /// <summary>
         /// 已同意次数
         /// </summary>

+ 1 - 1
src/Hotline.Share/Dtos/Order/OrderStartFlowDto.cs

@@ -207,7 +207,7 @@ namespace Hotline.Share.Dtos.Order
         /// <summary>
         /// 追加奖励人开户行
         /// </summary>
-        public string? AwardOpenBack { get; set; }
+        public string? AwardOpenBank { get; set; }
 
         /// <summary>
         /// 核实方式

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

@@ -152,4 +152,9 @@ public record QueryOrderPublishDto : PagedKeywordRequest
     /// 国家平台转办件
     /// </summary>
     public bool? Isgjzwfwpt { get; set; }
+
+    /// <summary>
+    /// 省来源分类 1:政民互动直派 2:政民互动  3:省12345
+    /// </summary>
+    public string? ProvinceChannel { get; set; }
 }

+ 86 - 3
src/Hotline.Share/Dtos/Snapshot/OrderDeclareDto.cs

@@ -9,21 +9,104 @@ using System.Xml.Linq;
 namespace Hotline.Share.Dtos.Snapshot;
 public class OrderDeclareItemsOutDto
 {
+    /// <summary>
+    /// 上报区域
+    /// </summary>
     public string AreaCode { get; set; }
+
+    /// <summary>
+    /// 区域名称
+    /// </summary>
     public string AreaName { get; set; }
-    public string EventType { get; set; }
+
+    /// <summary>
+    /// 申报类型
+    /// 0 主动申报;1 举报上报 ;2 社会排查
+    /// </summary>
+    public int EventType { get; set; }
+
+    /// <summary>
+    /// 作业地点
+    /// </summary>
     public string WorkAddress { get; set; }
+
+    /// <summary>
+    /// 上报时间
+    /// </summary>
     public DateTime CreatedTime { get; set; }
-    public string WorkType { get; set; }
+
+    /// <summary>
+    /// 作业类别
+    /// 0 电焊 1 气割 2 其它
+    /// </summary>
+    public int WorkType { get; set; }
+
+    /// <summary>
+    /// 来源
+    /// 1(小程序) 2(12345) 3(其它)
+    /// </summary>
     public int Source { get; set; }
+
+    /// <summary>
+    /// 作业开始时间
+    /// </summary>
     public DateTime WorkTimeStart { get; set; }
+
+    /// <summary>
+    /// 作业结束时间
+    /// </summary>
     public DateTime WorkTimeStop { get; set; }
+
+    /// <summary>
+    /// 现场描述情况内容
+    /// </summary>
     public string OnsiteSituateDescription { get; set; }
+
+    /// <summary>
+    /// 上报人员姓名
+    /// </summary>
     public string Name { get; set; }
+
+    /// <summary>
+    /// 上报人员联系方式
+    /// </summary>
     public string Phone { get; set; }
+
+    /// <summary>
+    /// 工单编号
+    /// </summary>
     public string EventId { get; set; }
+
+    /// <summary>
+    /// 场所类别编码
+    /// </summary>
     public string PlaceType { get; set; }
 }
 
 public class OrderDeclareItemsInDto
-{ }
+{
+    /// <summary>
+    /// JsonData
+    /// </summary>
+    public JsonData JsonData { get; set; }
+}
+
+public class JsonData
+{
+    /// <summary>
+    /// Code
+    /// </summary>
+    public string Code { get; set; }
+
+    public AcceptContent AcceptContent { get; set; }
+}
+
+public class AcceptContent
+{
+    public string DisposeDate { get; set; }
+
+    /// <summary>
+    /// 1:办结时间  2:受理时间
+    /// </summary>
+    public int Tyep { get; set; }
+}

+ 12 - 2
src/Hotline.Share/Dtos/Snapshot/OrderDto.cs

@@ -122,6 +122,16 @@ public class AddSnapshotOrderInDto : Position
     /// </summary>
     public string? WorkplaceName { get; set; }
 
+    /// <summary>
+    /// 作业区域
+    /// </summary>
+    public string WorkArea { get; set; }
+
+    /// <summary>
+    /// 作业区域Id
+    /// </summary>
+    public string WorkAreaId { get; set; }
+
     /// <summary>
     /// 作业时间
     /// </summary>
@@ -1093,7 +1103,7 @@ public class LabeledOrderSnapshotItemsOutDto
     public DateTime? LabelTime { get; set; }
 }
 
-public record LabelOrderSnapshotItemsInDto : PagedRequest
+public record SignOrderSnapshotItemsInDto : PagedRequest
 {
     /// <summary>
     /// No
@@ -1114,7 +1124,7 @@ public record LabelOrderSnapshotItemsInDto : PagedRequest
     public int Status { get; set; }
 }
 
-public class LabelOrderSnapshotItemsOutDto
+public class SignOrderSnapshotItemsOutDto
 {
     /// <summary>
     /// Id

+ 122 - 1
src/Hotline.Share/Dtos/Snapshot/RedPackDto.cs

@@ -1,7 +1,9 @@
-using Hotline.Share.Enums.Snapshot;
+using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Snapshot;
 using Hotline.Share.Requests;
 using Hotline.Share.Tools;
 using System.ComponentModel.DataAnnotations;
+using XF.Utility.EnumExtensions;
 
 namespace Hotline.Share.Dtos.Snapshot;
 public class RedPackOutDto 
@@ -151,3 +153,122 @@ public class UpdateRedPackRecordInDto
     public string ReplenishTypeId { get; set; }
 }
 
+
+/// <summary>
+/// 补充发放OutDto
+/// </summary>
+public class SnapshotRedPackRecordSupplementItemsOutDto
+{
+    /// <summary>
+    /// OrderId
+    /// </summary>
+    public string OrderId { get; set; }
+
+    /// <summary>
+    /// 信件状态
+    /// </summary>
+    public EOrderStatus Status { get; set; }
+
+    /// <summary>
+    /// 信件状态
+    /// </summary>
+    public string StatusTxt => Status.GetDescription();
+
+    /// <summary>
+    /// 来源
+    /// </summary>
+    public string SourceChannel { get; set; }
+
+    /// <summary>
+    /// 受理编号
+    /// </summary>
+    public string No { get; set; }
+
+    /// <summary>
+    /// 标题
+    /// </summary>
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 行业
+    /// </summary>
+    public string IndustryName { get; set; }
+
+    /// <summary>
+    /// 来电人电话
+    /// </summary>
+    public string FromPhone { get; set; }
+
+    /// <summary>
+    /// 区域
+    /// </summary>
+    public string County { get; set; }
+
+    /// <summary>
+    /// 补发金额
+    /// </summary>
+    public double ReplenishAmount { get; set; }
+
+    /// <summary>
+    /// 姓名
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 卡号
+    /// </summary>
+    public string BankCardNo { get; set; }
+
+    /// <summary>
+    /// 开户行
+    /// </summary>
+    public string OpenBank { get; set; }
+
+    /// <summary>
+    /// 补发放时间
+    /// </summary>
+    public DateTime CreationTime { get; set; }
+
+    /// <summary>
+    /// 补充发放人员
+    /// </summary>
+    public string CreatorName { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    public string Remark { get; set; }
+}
+
+public record SnapshotRedPackRecordSupplementItemsInDto : PagedRequest
+{
+    /// <summary>
+    /// 受理编号
+    /// </summary>
+    public string? No { get; set; }
+
+    /// <summary>
+    /// 标题
+    /// </summary>
+    public string? Title { get; set; }
+
+    /// <summary>
+    /// 来电人电话
+    /// </summary>
+    public string? FromPhone { get; set; }
+
+    /// <summary>
+    /// 发送时间
+    /// </summary>
+    public DateTime? BeginCreationTime { get; set; }
+
+    /// <summary>
+    /// 发送时间
+    /// </summary>
+    public DateTime? EndCreationTime { get; set; }
+
+    /// <summary>
+    /// 行业类型
+    /// </summary>
+    public string? IndustryId { get; set; }
+}

+ 29 - 0
src/Hotline.Share/Enums/Snapshot/EJobType.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Share.Enums.Snapshot;
+public enum EJobType
+{
+
+    /// <summary>
+    /// 电焊
+    /// </summary>
+    [Description("电焊")]
+    Electric,
+
+    /// <summary>
+    /// 气割
+    /// </summary>
+    [Description("气割")]
+    Gas,
+
+    /// <summary>
+    /// 其他
+    /// </summary>
+    [Description("其他")]
+    Othoer
+}

+ 4 - 1
src/Hotline.Share/Requests/PagedKeywordRequest.cs

@@ -245,7 +245,10 @@ public record PublishedPagedRequest : PagedKeywordRequest
     /// </summary>
     public EIdentityType? IdentityType { get; set; }
 
-
+    /// <summary>
+    /// 省来源分类 1:政民互动直派 2:政民互动  3:省12345
+    /// </summary>
+    public string? ProvinceChannel { get; set; }
 }
 
 public record HotspotSubtotalReportPagedRequest : ReportPagedRequest

+ 5 - 2
src/Hotline/Orders/DatabaseEventHandler/OrderVisitDetailEventHandler.cs

@@ -45,26 +45,29 @@ public class OrderVisitDetailEventHandler : IUpdateDatabaseEvent<OrderVisitDetai
         var name = "回填Order回访字段";
         if (visit.VisitTarget == EVisitTarget.Org && visit.OrgProcessingResults != null)
         {
+            if (visit.OrgProcessingResults.Value == "不满意") return;
+
             var orderId = _orderVisitRepository.Queryable()
                 .Where(m => m.Id == visit.VisitId)
                 .Select(m => new { m.OrderId, m.No })
                 .First();
             _orderRepository.Updateable()
                 .SetColumns(m => m.OrgProcessingResults == visit.OrgProcessingResults)
-                .Where(m => m.Id == orderId.OrderId)
+                .Where(m => m.Id == orderId.OrderId && m.Status == EOrderStatus.Visited)
                 .ExecuteCommand();
             _systemLogRepository.Add(name, $"OrgProcessingResults: {visit.OrgProcessingResults.ToJson()}", orderId.No, orderId.No, 1);
         }
 
         if (visit.VisitTarget == EVisitTarget.Seat && visit.SeatEvaluate != null)
         {
+            if (visit.SeatEvaluate == ESeatEvaluate.NoSatisfied || visit.SeatEvaluate == ESeatEvaluate.VeryNoSatisfied) return;
             var orderId = _orderVisitRepository.Queryable()
                 .Where(m => m.Id == visit.VisitId)
                 .Select(m => new { m.OrderId, m.No })
                 .First();
             _orderRepository.Updateable()
                 .SetColumns(m => m.SeatEvaluate == visit.SeatEvaluate)
-                .Where(m => m.Id == orderId.OrderId)
+                .Where(m => m.Id == orderId.OrderId && m.Status == EOrderStatus.Visited)
                 .ExecuteCommand();
             _systemLogRepository.Add(name, $"SeatEvaluate: {visit.SeatEvaluate}",orderId.No, orderId.No, 1);
         }

+ 1 - 0
src/Hotline/Snapshot/Interfaces/IIndustryRepository.cs

@@ -9,5 +9,6 @@ using XF.Domain.Repository;
 namespace Hotline.Snapshot.Interfaces;
 public interface IIndustryRepository : IRepository<Industry>
 {
+    Task<IList<dynamic>> GetDataBaseAsync();
     Task<double> GetIntervalTimeAsync(string industryId, double defaultValue, CancellationToken cancellationToken);
 }

+ 11 - 0
src/Hotline/Snapshot/Interfaces/ISupplementRecordRepository.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Repository;
+
+namespace Hotline.Snapshot.Interfaces;
+public interface ISupplementRecordRepository : IRepository<SupplementRecord>
+{
+}

+ 14 - 3
src/Hotline/Snapshot/OrderSnapshot.cs

@@ -45,7 +45,7 @@ public class OrderSnapshot : CreationSoftDeleteEntity
     /// 作业类型
     /// </summary>
     [SugarColumn(ColumnDescription = "作业类型")]
-    public string? JobType { get; set; }
+    public EJobType? JobType { get; set; }
 
     /// <summary>
     /// 经营单位类别
@@ -65,6 +65,18 @@ public class OrderSnapshot : CreationSoftDeleteEntity
     [SugarColumn(ColumnDescription = "场所名称")]
     public string? WorkplaceName { get; set; }
 
+    /// <summary>
+    /// 作业区域
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业区域")]
+    public string? WorkArea { get; set; }
+
+    /// <summary>
+    /// 作业区域Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "作业区域Id")]
+    public string? WorkAreaId { get; set; }
+
     /// <summary>
     /// 作业时间
     /// </summary>
@@ -187,7 +199,7 @@ public class OrderSnapshot : CreationSoftDeleteEntity
     /// 追加奖励人开户银行
     /// </summary>
     [SugarColumn(ColumnDescription = "追加奖励人开户银行")]
-    public string? AwardOpenBack { get; set; }
+    public string? AwardOpenBank { get; set; }
 
     /// <summary>
     /// 追加奖励人姓名
@@ -324,5 +336,4 @@ public class OrderSnapshot : CreationSoftDeleteEntity
     /// </summary>
     [SugarColumn(ColumnDescription = "购气单位/个人名称")]
     public string? CompanyName { get; set; }
-
 }

+ 0 - 30
src/Hotline/Snapshot/RedPackAudit.cs

@@ -61,36 +61,6 @@ public class RedPackAudit : CreationSoftDeleteEntity
     [SugarColumn(ColumnDescription = "实发金额")]
     public double? AcutalAmount { get; set; }
 
-    /// <summary>
-    /// 补充发放金额
-    /// </summary>
-    [SugarColumn(ColumnDescription = "补充发放金额")]
-    public double? ReplenishAmount { get; set; }
-
-    /// <summary>
-    /// 补充发放时间
-    /// </summary>
-    [SugarColumn(ColumnDescription = "补充发放时间")]
-    public DateTime? ReplenishTime { get; set; }
-
-    /// <summary>
-    /// 补充发放备注
-    /// </summary>
-    [SugarColumn(ColumnDescription = "补充发放备注")]
-    public string? ReplenishRemark { get; set; }
-
-    /// <summary>
-    /// 补充发放类型
-    /// </summary>
-    [SugarColumn(ColumnDescription = "补充发放类型")]
-    public string? ReplenishType { get; set; }
-
-    /// <summary>
-    /// 补充发放类型Id
-    /// </summary>
-    [SugarColumn(ColumnDescription = "补充发放类型Id")]
-    public string? ReplenishTypeId { get; set; }
-
     /// <summary>
     /// 市民奖励发放结果
     /// </summary>

+ 101 - 0
src/Hotline/Snapshot/SupplementRecord.cs

@@ -0,0 +1,101 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Repository;
+
+namespace Hotline.Snapshot;
+
+/// <summary>
+/// 补充发放记录
+/// </summary>
+[Description("补充发放记录")]
+public class SupplementRecord : FullStateEntity
+{
+    /// <summary>
+    /// OrderId
+    /// </summary>
+    [SugarColumn(ColumnDescription = "OrderId")]
+    public string OrderId { get; set; }
+
+    /// <summary>
+    /// No
+    /// </summary>
+    [SugarColumn(ColumnDescription ="No")]
+    public string No { get; set; }
+
+    /// <summary>
+    /// RedPackAuditId
+    /// </summary>
+    [SugarColumn(ColumnDescription = "RedPackAuditId")]
+    public string RedPackAuditId { get; set; }
+
+    /// <summary>
+    /// RedPackRecordId
+    /// </summary>
+    [SugarColumn(ColumnDescription = "RedPackRecordId")]
+    public string RedPackRecordId { get; set; }
+
+    /// <summary>
+    /// 行业
+    /// </summary>
+    [SugarColumn(ColumnDescription = "行业名称")]
+    public string IndustryName { get; set; }
+
+    /// <summary>
+    /// 行业Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "行业Id")]
+    public string? IndustryId { get; set; }
+
+    /// <summary>
+    /// 补充发放金额
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充发放金额")]
+    public double? ReplenishAmount { get; set; }
+
+    /// <summary>
+    /// 补充发放时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充发放时间")]
+    public DateTime? ReplenishTime { get; set; }
+
+    /// <summary>
+    /// 补充发放备注
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充发放备注")]
+    public string? ReplenishRemark { get; set; }
+
+    /// <summary>
+    /// 补充发放类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充发放类型")]
+    public string? ReplenishType { get; set; }
+
+    /// <summary>
+    /// 补充发放类型Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "补充发放类型Id")]
+    public string? ReplenishTypeId { get; set; }
+
+    /// <summary>
+    /// 银行卡号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "银行卡号")]
+    public string? BankCardNo { get; set; }
+
+    /// <summary>
+    /// 开户行
+    /// </summary>
+    [SugarColumn(ColumnDescription = "开户行")]
+    public string? OpenBank { get; set; }
+
+    /// <summary>
+    /// 是否发送短信
+    /// </summary>
+    [SugarColumn(ColumnDescription = "是否发送短信")]
+    public bool IsSendSMS { get; set; }
+}

+ 1 - 1
src/Tr.Sdk/Tr.Sdk.csproj

@@ -9,7 +9,7 @@
   <ItemGroup>
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
-    <PackageReference Include="RestSharp" Version="110.2.0" />
+    <PackageReference Include="RestSharp" Version="112.1.0" />
   </ItemGroup>
 
   <ItemGroup>