Explorar o código

完成自动归档

qinchaoyue hai 5 meses
pai
achega
779474b0f6

+ 1 - 126
src/Hotline.Api/Controllers/OrderController.cs

@@ -358,132 +358,7 @@ public class OrderController : BaseController
             {
                 try
                 {
-                    OrderPublish orderPublish = new OrderPublish();
-                    orderPublish.OrderId = order.Id;
-                    orderPublish.No = order.No;
-                    orderPublish.PublishState = false; //当前写死为false
-                    orderPublish.ArrangeTitle = order.Title;
-                    orderPublish.ArrangeContent = order.Content;
-                    orderPublish.ArrangeOpinion = order.FileOpinion;
-                    orderPublish.ProPublishState = false;
-                    orderPublish.FeedBackPhone = order.Contact;
-                    orderPublish.CreatorName = _sessionContext.UserName;
-                    await _orderPublishRepository.AddAsync(orderPublish);
-                    order.Publish(orderPublish.PublishState);
-                    await _orderRepository.UpdateAsync(order);
-                    //推省上
-                    var publishPublishOrder = _mapper.Map<PublishPublishOrderDto>(orderPublish);
-                    publishPublishOrder.Order = _mapper.Map<OrderDto>(order);
-                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderPublishOrder, publishPublishOrder);
-
-                    //推应急管理局
-                    //是否开启
-                    var isOpenContingencyManagement =
-                        _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenContingencyManagement)?.SettingValue[0];
-                    if (isOpenContingencyManagement == "true")
-                        await _publisher.PublishAsync(new ContingencyManagementNotify(order, order.Title, order.Content, order.ActualOpinion),
-                            PublishStrategy.ParallelWhenAll, HttpContext.RequestAborted);
-
-                    var orderVisit = new OrderVisit();
-                    orderVisit.No = order.No;
-                    orderVisit.OrderId = order.Id;
-                    orderVisit.VisitState = EVisitState.WaitForVisit;
-                    orderVisit.PublishTime = DateTime.Now;
-                    orderVisit.IsCanHandle = true;
-                    orderVisit.EmployeeId = _sessionContext.RequiredUserId;
-
-                    if (_appOptions.Value.IsZiGong)
-                    {
-                        orderVisit.EmployeeId = string.Empty;
-                    }
-
-                    if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null } && !order.IsProvince)
-                    {
-                        orderVisit.VisitState = EVisitState.Visited;
-                        orderVisit.VisitTime = DateTime.Now;
-                        orderVisit.VisitType = EVisitType.OtherVisit;
-                        orderVisit.NowEvaluate = new Kv() { Key = "4", Value = "满意" };
-                        if (_appOptions.Value.IsZiGong)
-                        {
-                            // 根据禅道 自贡需求 Id_361, 第一条, 3小条需求;
-                            // 直办件归档后自动回访量需统计在“胡玲”的默认回访量中;
-                            orderVisit.EmployeeId = _systemSettingCacheManager.DefaultVisitEmployeeId;
-                        }
-                    }
-
-                    if (order.CounterSignType != ECounterSignType.Center)
-                    {
-                        orderVisit.IsCanAiVisit = true;
-                    }
-
-
-                    string visitId = await _orderVisitRepository.AddAsync(orderVisit);
-
-                    //新增回访信息
-                    var visitedDetail = new List<OrderVisitDetail>();
-
-                    var seatDetail = new OrderVisitDetail();
-                    seatDetail.VisitId = visitId;
-                    seatDetail.VisitTarget = EVisitTarget.Seat;
-
-
-                    var orgDetail = new OrderVisitDetail();
-                    orgDetail.VisitId = visitId;
-                    orgDetail.VisitOrgCode = order.ActualHandleOrgCode;
-                    orgDetail.VisitOrgName = order.ActualHandleOrgName;
-                    orgDetail.VisitTarget = EVisitTarget.Org;
-                    if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null, IsProvince: false })
-                    {
-                        var satisfy = new Kv() { Key = "4", Value = "满意" };
-                        orgDetail.OrgProcessingResults = satisfy;
-                        //orgDetail.OrgHandledAttitude = satisfy;
-                    }
-
-                    visitedDetail.Add(orgDetail);
-
-                    if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null })
-                    {
-                        seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
-                        seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
-                        order.Visited("4", "满意");
-                        order.Status = EOrderStatus.Visited;
-                        await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
-                    }
-
-                    visitedDetail.Add(seatDetail);
-                    await _orderVisitedDetailRepository.AddRangeAsync(visitedDetail, HttpContext.RequestAborted);
-
-                    if (orderVisit.VisitState == EVisitState.Visited)
-                    {
-                        //推省上
-                        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited,
-                            new PublishVisitDto()
-                            {
-                                Order = _mapper.Map<OrderDto>(order),
-                                No = orderVisit.No,
-                                VisitType = orderVisit.VisitType,
-                                VisitName = orderVisit.CreatorName,
-                                VisitTime = orderVisit.VisitTime,
-                                VisitRemark = orderVisit.NowEvaluate?.Value,
-                                AreaCode = order.AreaCode!,
-                                SubjectResultSatifyCode = orderVisit.NowEvaluate?.Key,
-                                FirstSatisfactionCode = orderVisit.NowEvaluate?.Key,
-                                ClientGuid = ""
-                            }, cancellationToken: HttpContext.RequestAborted);
-                    }
-
-                    //推门户
-                    await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
-                    {
-                        Id = orderVisit.Id,
-                        Order = _mapper.Map<OrderDto>(order),
-                        OrderVisitDetails = _mapper.Map<List<VisitDetailDto>>(orderVisit.OrderVisitDetails),
-                        VisitName = _sessionContext.UserName,
-                        VisitTime = orderVisit.VisitTime,
-                        VisitType = orderVisit.VisitType,
-                        VisitState = orderVisit.VisitState,
-                        PublishTime = orderVisit.PublishTime,
-                    }, cancellationToken: HttpContext.RequestAborted);
+                    await _orderDomainService.OrderPublishAsync(order, HttpContext.RequestAborted);
                 }
                 catch
                 {

+ 32 - 2
src/Hotline.Application.Tests/Controller/OrderControllerTest.cs

@@ -1,7 +1,11 @@
 using AutoFixture;
+using Castle.DynamicProxy;
 using Hotline.Api.Controllers;
+using Hotline.Application.Orders.OrderPublishHandler;
 using Hotline.Application.Tests.Infrastructure;
 using Hotline.Application.Tests.Mock;
+using Hotline.FlowEngine.Notifications;
+using Hotline.FlowEngine.WorkflowModules;
 using Hotline.Identity.Accounts;
 using Hotline.Identity.Roles;
 using Hotline.Orders;
@@ -13,6 +17,7 @@ using Hotline.Share.Enums.FlowEngine;
 using Hotline.Share.Enums.Settings;
 using Hotline.Share.Tools;
 using Hotline.Users;
+using MediatR;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.Testing;
@@ -34,8 +39,10 @@ public class OrderControllerTest : TestBase
     private readonly IRepository<Hotspot> _hotspotRepository;
     private readonly IOrderRepository _orderRepository;
     private readonly OrderServiceMock _orderServiceMock;
+    private readonly IRepository<OrderPublish> _orderPublishRepository;
+    private readonly INotificationHandler<EndWorkflowNotify> _orderPublishEndWorkflowHandler;
 
-    public OrderControllerTest(IAccountRepository accountRepository, IRepository<Role> roleRepository, UserController userController, IRepository<Hotspot> hotspotRepository, OrderController orderController, IOrderRepository orderRepository, IServiceScopeFactory scopeFactory, IRepository<User> userRepository, OrderServiceMock orderServiceMock) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository)
+    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) : base(accountRepository, roleRepository, userController, scopeFactory, userRepository)
     {
         _hotspotRepository = hotspotRepository;
         _orderController = orderController;
@@ -45,6 +52,29 @@ public class OrderControllerTest : TestBase
         };
         _orderRepository = orderRepository;
         _orderServiceMock = orderServiceMock;
+        _orderPublishRepository = orderPublishRepository;
+        _orderPublishEndWorkflowHandler = orderPublishEndWorkflowHandler;
+    }
+
+    [Fact]
+    public async Task AutoPublish_Test()
+    {
+        SetZuoXi();
+        var order = _orderServiceMock.CreateOrder()
+            .办理到派单员()
+            .办理到归档(SetPaiDanYuan)
+            .GetCreateResult();
+        await _orderPublishEndWorkflowHandler.Handle(new EndWorkflowNotify(
+        new Hotline.FlowEngine.Workflows.Workflow
+        {
+            ModuleCode = WorkflowModuleConsts.OrderHandle,
+            ExternalId = order.Id
+        },
+        new Hotline.FlowEngine.Workflows.WorkflowTrace(),
+             new Share.Dtos.FlowEngine.BasicWorkflowDto()
+        ), new CancellationToken());
+        var publish = await _orderPublishRepository.GetAsync(m => m.No == order.No);
+        publish.ShouldNotBeNull(order.No);
     }
 
     [Fact]
@@ -59,7 +89,7 @@ public class OrderControllerTest : TestBase
         SetZuoXi();
         var order = _orderServiceMock.CreateOrder()
             .办理到派单员()
-            .办理到归档(SetPaiDanYuan, data => data.IsStepUrgent = true, workflow => 
+            .办理到归档(SetPaiDanYuan, data => data.IsStepUrgent = true, workflow =>
             {
                 workflow.BusinessType = EBusinessType.DepartmentLeader;
                 workflow.Opinion = "测试保存勾选紧急";

+ 3 - 0
src/Hotline.Application.Tests/Startup.cs

@@ -38,6 +38,8 @@ using Hotline.Identity.Accounts;
 using Hotline.Application.Tests.Controller;
 using Hotline.Application.Tests.Infrastructure;
 using Hotline.Authentications;
+using Hotline.Application.Orders.OrderPublishHandler;
+using Hotline.FlowEngine.Notifications;
 
 namespace Hotline.Application.Tests;
 public class Startup
@@ -151,6 +153,7 @@ public class Startup
             services.AddScoped<ISessionContextProvider, SessionContextProvider>();
             services.AddScoped<ICallApplication, XingTangCallApplication>();
             services.AddScoped<OrderServiceMock>();
+            services.AddScoped<INotificationHandler<EndWorkflowNotify>, OrderPublishEndWorkflowHandler>();
             //ServiceLocator.Instance = services.BuildServiceProvider();
         }
 

+ 101 - 0
src/Hotline.Application/Orders/OrderPublishHandler/OrderPublishEndWorkflowHandler.cs

@@ -0,0 +1,101 @@
+using DotNetCore.CAP;
+using Hotline.Caching.Interfaces;
+using Hotline.Configurations;
+using Hotline.ContingencyManagement.Notifies;
+using Hotline.EventBus;
+using Hotline.FlowEngine.Notifications;
+using Hotline.FlowEngine.WorkflowModules;
+using Hotline.Orders;
+using Hotline.Settings;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Order;
+using Hotline.Share.Enums.FlowEngine;
+using Hotline.Share.Enums.Order;
+using Hotline.Share.Tools;
+using Mapster;
+using MediatR;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Authentications;
+using XF.Domain.Repository;
+
+namespace Hotline.Application.Orders.OrderPublishHandler;
+
+/// <summary>
+/// 中心直办件归档后默认自动发布
+/// </summary>
+public class OrderPublishEndWorkflowHandler : INotificationHandler<EndWorkflowNotify>
+{
+    private readonly IOrderRepository _orderRepository;
+    private readonly Publisher _publisher;
+    private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
+    private readonly IRepository<OrderPublish> _orderPublishRepository;
+    private readonly ISessionContextProvider _sessionContextProvider;
+    private readonly ICapPublisher _capPublisher;
+    private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+    private readonly IOrderDomainService _orderDomainService;
+    private readonly IOrderVisitRepository _orderVisitRepository;
+    private readonly IRepository<OrderVisitDetail> _orderVisitedDetailRepository;
+    private readonly ILogger<OrderPublishEndWorkflowHandler> _logger;
+    private readonly ISystemLogRepository _systemLogRepository;
+    private const string Name = "中心直办件归档后默认自动发布";
+
+    public OrderPublishEndWorkflowHandler(IOrderRepository orderRepository, IRepository<OrderPublish> orderPublishRepository, ISessionContextProvider sessionContextProvider, ICapPublisher capPublisher, ISystemSettingCacheManager systemSettingCacheManager, Publisher publisher, IOptionsSnapshot<AppConfiguration> appOptions, IOrderVisitRepository orderVisitRepository, IRepository<OrderVisitDetail> orderVisitedDetailRepository, ILogger<OrderPublishEndWorkflowHandler> logger, ISystemLogRepository systemLogRepository, IOrderDomainService orderDomainService)
+    {
+        _orderRepository = orderRepository;
+        _orderPublishRepository = orderPublishRepository;
+        _sessionContextProvider = sessionContextProvider;
+        _capPublisher = capPublisher;
+        _systemSettingCacheManager = systemSettingCacheManager;
+        _publisher = publisher;
+        _appOptions = appOptions;
+        _orderVisitRepository = orderVisitRepository;
+        _orderVisitedDetailRepository = orderVisitedDetailRepository;
+        _logger = logger;
+        _systemLogRepository = systemLogRepository;
+        _orderDomainService = orderDomainService;
+    }
+
+    public async Task Handle(EndWorkflowNotify notification, CancellationToken cancellationToken)
+    {
+        try
+        {
+            if (_systemSettingCacheManager.AutomaticPublishOrder == false)
+            {
+                return;
+            }
+            if (notification.Workflow.ModuleCode != WorkflowModuleConsts.OrderHandle)
+                return;
+            var order = await _orderRepository.GetAsync(notification.Workflow.ExternalId, cancellationToken);
+            if (order == null)
+            {
+                await _systemLogRepository.AddAsync(Name, notification.Workflow.ExternalId, "根据 workflow.ExternalId 查询 order 为空");
+                return;
+            }
+            var checkResult = order.AutoPublishCheck();
+            if (checkResult.NotNullOrEmpty())
+            {
+                await _systemLogRepository.AddAsync(Name, order.Id, checkResult);
+                return;
+            }
+
+            if (order.ProcessType != EProcessType.Zhiban)
+            {
+                await _systemLogRepository.AddAsync(Name, order.Id, "非中心直办件");
+                return;
+            }
+
+            await _orderDomainService.OrderPublishAsync(order, cancellationToken);
+        }
+        catch (Exception e)
+        {
+            await _systemLogRepository.AddAsync(Name, notification.Workflow.ExternalId, $"系统异常: {e.Message}");
+        }
+    }
+}

+ 40 - 0
src/Hotline.Repository.SqlSugar/System/SystemLogRepository.cs

@@ -0,0 +1,40 @@
+using Hotline.Repository.SqlSugar.DataPermissions;
+using Hotline.Settings;
+using Hotline.Share.Tools;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Dependency;
+
+namespace Hotline.Repository.SqlSugar.System;
+public class SystemLogRepository : BaseRepository<SystemLog>, ISystemLogRepository, IScopeDependency
+{
+    public SystemLogRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder) : base(uow, dataPermissionFilterBuilder)
+    {
+    }
+
+    public async Task AddAsync(string name, string executeParam = "", string remark = "", string executeUrl = "", int status = 0)
+    {
+        var entity = new SystemLog 
+        {
+            Name = name,
+            ExecuteParam = executeParam,
+            ExecuteUrl = executeUrl,
+            Remark = remark,
+            Status = status
+        };
+        if (executeUrl.IsNullOrEmpty())
+        {
+            try
+            {
+                entity.ExecuteUrl = new StackTrace().GetFrame(1).GetMethod().Name;
+            }
+            catch{ }
+        }
+        await AddAsync(entity);
+    }
+}

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

@@ -20,5 +20,10 @@ namespace Hotline.Caching.Interfaces
         /// </summary>
         string DefaultVisitEmployeeId { get; }
         int FixedQueryCount { get; }
+
+        /// <summary>
+        /// 自动发布中心直办归档工单
+        /// </summary>
+        bool AutomaticPublishOrder { get; }
     }
 }

+ 32 - 1
src/Hotline/Caching/Services/SystemSettingCacheManager.cs

@@ -39,7 +39,7 @@ namespace Hotline.Caching.Services
         public int EffectiveTimes
             => int.Parse(GetSetting(SettingConstants.EffectiveTimes)?.SettingValue[0]);
 
-        public int ConnectByeTimes 
+        public int ConnectByeTimes
             => int.Parse(GetSetting(SettingConstants.ConnectByeTimes)?.SettingValue[0]);
 
         public int NoConnectByeTimes => int.Parse(GetSetting(SettingConstants.NoConnectByeTimes)?.SettingValue[0]);
@@ -55,5 +55,36 @@ namespace Hotline.Caching.Services
         public string DefaultVisitEmployeeId => GetSetting(SettingConstants.DefaultVisitEmployeeId)?.SettingValue[0].Trim().ToString();
 
         public int FixedQueryCount => int.Parse(GetSetting(SettingConstants.FixedQueryCount)?.SettingValue[0]);
+
+        public bool AutomaticPublishOrder
+        {
+            get
+            {
+
+                try
+                {
+                    var value = GetSetting(SettingConstants.AutomaticPublishOrder)?.SettingValue[0];
+                    if (value == null) return false;
+                    if (value.Trim() == "true")
+                    {
+                        return true;
+                    }
+                }
+                catch (UserFriendlyException e)
+                {
+                    if (e.Message.Contains("无效系统设置"))
+                    {
+                        _systemSettingRepository.AddAsync(new SystemSetting 
+                        {
+                            Code = SettingConstants.AutomaticPublishOrder,
+                            SettingName = "自动发布中心直办归档工单",
+                            SettingValue = ["false"],
+                            Remark = "用于中心直办件归档后默认自动发布, 开启就自动发布.true 或者 false"
+                        });
+                    }
+                }
+                return false;
+            }
+        }
     }
 }

+ 1 - 2
src/Hotline/Orders/IOrderDomainService.cs

@@ -102,7 +102,6 @@ namespace Hotline.Orders
         /// </summary>
         /// <returns></returns>
         Task SendOverTimeSms(CancellationToken cancellationToken);
-
-
+        Task OrderPublishAsync(Order order, CancellationToken cancellationToken);
     }
 }

+ 22 - 4
src/Hotline/Orders/Order.cs

@@ -1,5 +1,6 @@
 using Hotline.CallCenter.Calls;
 using Hotline.FlowEngine.Workflows;
+using Hotline.Settings;
 using Hotline.Settings.Hotspots;
 using Hotline.Share.Dtos.File;
 using Hotline.Share.Enums.FlowEngine;
@@ -11,6 +12,7 @@ using System.ComponentModel;
 using XF.Domain.Exceptions;
 using XF.Domain.Extensions;
 using XF.Domain.Repository;
+using XF.Utility.EnumExtensions;
 
 namespace Hotline.Orders
 {
@@ -1047,7 +1049,8 @@ namespace Hotline.Orders
 		/// </summary>
 		[SugarColumn(ColumnDescription = "话务提醒是否转办")]
 		public bool? IsForwarded { get; set; }
-	}
+
+    }
 
     public partial class Order
     {
@@ -1359,10 +1362,25 @@ namespace Hotline.Orders
             }
         }
 
-        #endregion
-    }
+        /// <summary>
+        /// 自动发布条件检测
+        /// </summary>
+        /// <returns></returns>
+        /// <exception cref="NotImplementedException"></exception>
+        public string AutoPublishCheck()
+        {
+            if (CounterSignType != null)
+                return "会签工单自动发布失败;";
+            if (IsProvince)
+                return "省工单自动发布失败;";
+            if (Status != EOrderStatus.Filed)
+                return "工单状态非 已归档, " + Status.GetDescription();
+            return "";
+        }
+    #endregion
+}
 
-    public class UnsignedOrder
+public class UnsignedOrder
     {
         public Order Order { get; set; }
 

+ 164 - 2
src/Hotline/Orders/OrderDomainService.cs

@@ -24,6 +24,14 @@ using SqlSugar;
 using Hotline.Push.Notifies;
 using Hotline.Share.Enums.Push;
 using MediatR;
+using Hotline.Authentications;
+using Hotline.ContingencyManagement.Notifies;
+using Hotline.EventBus;
+using Hotline.Share.Enums.FlowEngine;
+using Mapster;
+using Microsoft.AspNetCore.Builder.Extensions;
+using Hotline.Configurations;
+using Microsoft.Extensions.Options;
 
 namespace Hotline.Orders;
 
@@ -38,16 +46,19 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
     private readonly ITypedCache<CacheOrderNO> _cacheOrderNo;
     private readonly ISessionContext _sessionContext;
     private readonly ICapPublisher _capPublisher;
+    private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
     private readonly IMapper _mapper;
     private readonly ILogger<OrderDomainService> _logger;
     private readonly IFileRepository _fileRepository;
     private readonly IRepository<Scheduling> _schedulingRepository;
+    private readonly Publisher _publisher;
+    private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
     private readonly IRepository<User> _userRepository;
     private readonly ISystemSettingCacheManager _systemSettingCacheManager;
     private readonly IWorkflowDomainService _workflowDomainService;
     private readonly IRepository<Hotspot> _hotspotRepository;
     private readonly IMediator _mediator;
-
+    private readonly IRepository<WorkflowStep> _workflowStepRepository;
 
     public OrderDomainService(
         IOrderRepository orderRepository,
@@ -68,7 +79,10 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         IRepository<Scheduling> schedulingRepository,
         IWorkflowDomainService workflowDomainService,
         IRepository<Hotspot> hotspotRepository,
-        IMediator mediator)
+        IMediator mediator,
+        Publisher publisher,
+        IRepository<OrderVisitDetail> orderVisitDetailRepository,
+        IRepository<WorkflowStep> workflowStepRepository)
     {
         _orderRepository = orderRepository;
         _orderRedoRepository = orderRedoRepository;
@@ -88,6 +102,153 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         _workflowDomainService = workflowDomainService;
         _hotspotRepository = hotspotRepository;
         _mediator = mediator;
+        _publisher = publisher;
+        _orderVisitDetailRepository = orderVisitDetailRepository;
+        _workflowStepRepository = workflowStepRepository;
+    }
+
+    public async Task OrderPublishAsync(Order order, CancellationToken cancellationToken)
+    {
+        OrderPublish orderPublish = new()
+        {
+            OrderId = order.Id,
+            No = order.No,
+            PublishState = false, //当前写死为false
+            ArrangeTitle = order.Title,
+            ArrangeContent = order.Content,
+            ArrangeOpinion = order.FileOpinion,
+            ProPublishState = false,
+            FeedBackPhone = order.Contact,
+            CreatorName = _sessionContext.UserName
+        };
+        await _orderPublishRepository.AddAsync(orderPublish, cancellationToken);
+        order.Publish(orderPublish.PublishState);
+        await _orderRepository.UpdateAsync(order, cancellationToken);
+        //推省上
+        var publishPublishOrder = orderPublish.Adapt<PublishPublishOrderDto>();
+        publishPublishOrder.Order = order.Adapt<OrderDto>();
+        //查询实际办理附件
+        if (!string.IsNullOrEmpty(order.ActualHandleStepId)) 
+        {
+            var actualHandleStep = await _workflowStepRepository.GetAsync(order.ActualHandleStepId, cancellationToken);
+            publishPublishOrder.FileJsons = actualHandleStep?.FileJson;
+        }
+
+        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderPublishOrder, publishPublishOrder, cancellationToken: cancellationToken);
+
+        //推应急管理局
+        //是否开启
+        var isOpenContingencyManagement =
+            _systemSettingCacheManager.GetSetting(SettingConstants.IsOpenContingencyManagement)?.SettingValue[0];
+        if (isOpenContingencyManagement == "true")
+            await _publisher.PublishAsync(new ContingencyManagementNotify(order, order.Title, order.Content, order.ActualOpinion),
+                PublishStrategy.ParallelWhenAll, cancellationToken);
+
+        var orderVisit = new OrderVisit
+        {
+            No = order.No,
+            OrderId = order.Id,
+            VisitState = EVisitState.WaitForVisit,
+            PublishTime = DateTime.Now,
+            IsCanHandle = true,
+            EmployeeId = _sessionContext.RequiredUserId
+        };
+        if (!order.IsProvince)
+        {
+            orderVisit.EmployeeId = _sessionContext.RequiredUserId;
+        }
+
+        if (_appOptions.Value.IsZiGong)
+        {
+            orderVisit.EmployeeId = string.Empty;
+        }
+
+        if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null } && !order.IsProvince)
+        {
+            orderVisit.VisitState = EVisitState.Visited;
+            orderVisit.VisitTime = DateTime.Now;
+            orderVisit.VisitType = EVisitType.OtherVisit;
+            orderVisit.NowEvaluate = new Kv() { Key = "4", Value = "满意" };
+            if (_appOptions.Value.IsZiGong)
+            {
+                // 根据禅道 自贡需求 Id_361, 第一条, 3小条需求;
+                // 直办件归档后自动回访量需统计在“胡玲”的默认回访量中;
+                orderVisit.EmployeeId = _systemSettingCacheManager.DefaultVisitEmployeeId;
+            }
+        }
+
+        if (order.CounterSignType != ECounterSignType.Center)
+        {
+            orderVisit.IsCanAiVisit = true;
+        }
+
+        string visitId = await _orderVisitRepository.AddAsync(orderVisit);
+
+        //新增回访信息
+        var visitedDetail = new List<OrderVisitDetail>();
+
+        var seatDetail = new OrderVisitDetail();
+        seatDetail.VisitId = visitId;
+        seatDetail.VisitTarget = EVisitTarget.Seat;
+
+
+        var orgDetail = new OrderVisitDetail();
+        orgDetail.VisitId = visitId;
+        orgDetail.VisitOrgCode = order.ActualHandleOrgCode;
+        orgDetail.VisitOrgName = order.ActualHandleOrgName;
+        orgDetail.VisitTarget = EVisitTarget.Org;
+        if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null, IsProvince: false })
+        {
+            var satisfy = new Kv() { Key = "4", Value = "满意" };
+            orgDetail.OrgProcessingResults = satisfy;
+            //orgDetail.OrgHandledAttitude = satisfy;
+        }
+
+        visitedDetail.Add(orgDetail);
+
+        if (order is { ProcessType: EProcessType.Zhiban, CounterSignType: null })
+        {
+            seatDetail.VoiceEvaluate = EVoiceEvaluate.Satisfied;
+            seatDetail.SeatEvaluate = ESeatEvaluate.Satisfied;
+            order.Visited("4", "满意");
+            order.Status = EOrderStatus.Visited;
+            await _orderRepository.UpdateAsync(order, cancellationToken);
+        }
+
+        visitedDetail.Add(seatDetail);
+        await _orderVisitDetailRepository.AddRangeAsync(visitedDetail, cancellationToken);
+
+        if (order.IsProvince == false && orderVisit.VisitState == EVisitState.Visited)
+        {
+            //推省上
+            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisited,
+                new PublishVisitDto()
+                {
+                    Order = order.Adapt<OrderDto>(),
+                    No = orderVisit.No,
+                    VisitType = orderVisit.VisitType,
+                    VisitName = orderVisit.CreatorName,
+                    VisitTime = orderVisit.VisitTime,
+                    VisitRemark = orderVisit.NowEvaluate?.Value,
+                    AreaCode = order.AreaCode!,
+                    SubjectResultSatifyCode = orderVisit.NowEvaluate?.Key,
+                    FirstSatisfactionCode = orderVisit.NowEvaluate?.Key,
+                    ClientGuid = ""
+                }, cancellationToken: cancellationToken);
+        }
+
+        //推门户
+        await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderVisitedWeb, new PublishVisitAllDto()
+        {
+            Id = orderVisit.Id,
+            Order = order.Adapt<OrderDto>(),
+            OrderVisitDetails = orderVisit.OrderVisitDetails.Adapt<List<VisitDetailDto>>(),
+            VisitName = _sessionContext.UserName,
+            VisitTime = orderVisit.VisitTime,
+            VisitType = orderVisit.VisitType,
+            VisitState = orderVisit.VisitState,
+            PublishTime = orderVisit.PublishTime,
+        }, cancellationToken: cancellationToken);
     }
 
     public async Task<Order> GetOrderAsync(string? orderId, bool withHotspot = false, bool withAcceptor = false,
@@ -328,6 +489,7 @@ public class OrderDomainService : IOrderDomainService, IScopeDependency
         }
     }
     #endregion
+
     #region  工单校验- 交通类工单
 
     /// <summary>

+ 21 - 0
src/Hotline/Settings/ISystemLogRepository.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using XF.Domain.Repository;
+
+namespace Hotline.Settings;
+public interface ISystemLogRepository : IRepository<SystemLog>
+{
+    /// <summary>
+    /// 添加操作日志
+    /// </summary>
+    /// <param name="name">方法</param>
+    /// <param name="executeParam">入参</param>
+    /// <param name="executeUrl">地址</param>
+    /// <param name="remark">备注</param>
+    /// <param name="status">状态(0失败 1成功)</param>
+    /// <returns></returns>
+    Task AddAsync(string name, string executeParam = "", string remark = "", string executeUrl = "", int status = 0);
+}

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

@@ -565,5 +565,10 @@ namespace Hotline.Settings
         /// 上传文件格式显示
         /// </summary>
         public const string FileExt = "FileExt";
+
+        /// <summary>
+        /// 自动发布中心直办归档工单
+        /// </summary>
+        public const string AutomaticPublishOrder = "AutomaticPublishOrder";
     }
 }