TANG JIANG hace 1 año
padre
commit
cf52f94e7c

+ 73 - 0
src/Hotline.Share/Dtos/DataSharing/Province/ProvinceDistrecordResponse.cs

@@ -0,0 +1,73 @@
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Receive;
+
+namespace Hotline.Share.Dtos.DataSharing.Province
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public class ProvinceDistrecordResponse
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public StatusModel status { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public CustomModel custom { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public ReturnInfoModel ReturnInfo { get; set; }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class StatusModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public string code { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public string text { get; set; }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class CustomModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public List<GetCaseDistrecordSendModel> STEP_List { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public string CASE_SERIAL { get; set; }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class ReturnInfoModel
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public string Description { get; set; }
+    }
+}

+ 23 - 0
src/Hotline.Share/Dtos/DataSharing/Province/TokenRsp.cs

@@ -0,0 +1,23 @@
+using System.Text.Json.Serialization;
+
+namespace Hotline.Share.Dtos.DataSharing.Province
+{
+    [Serializable]
+    public class TokenRsp
+    {
+        [JsonPropertyName("custom")]
+        public TokenInfo TokenInfo { get; set; }
+    }
+
+    public class TokenInfo
+    {
+        [JsonPropertyName("access_token")]
+        public string AccessToken { get; set; }
+
+        [JsonPropertyName("refresh_token")]
+        public string RefreshToken { get; set; }
+
+        [JsonPropertyName("expires_in")]
+        public string ExpiresIn { get; set; }
+    }
+}

+ 337 - 0
src/Hotline/DataSharing/Province/DefaultPusher.cs

@@ -0,0 +1,337 @@
+using Hotline.Share.Dtos.DataSharing.Province;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Knowledge;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Receive;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Send;
+using Sharing.Province.Dtos.HuiJu.Send;
+
+namespace Hotline.DataSharing.Province;
+
+/// <summary>
+/// 默认策略(保持原数据策略)
+/// </summary>
+public class DefaultPusher : IProvincePusher
+{
+    private readonly HuiJuClient _huiJuClient;
+    private readonly XieTongClient _xieTongClient;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="huiJuClient"></param>
+    /// <param name="xieTongClient"></param>
+    public DefaultPusher(HuiJuClient huiJuClient, XieTongClient xieTongClient)
+    {
+        _huiJuClient = huiJuClient;
+        _xieTongClient = xieTongClient;
+    }
+
+    #region 协同-第一批次
+    /// <summary>
+    /// 服务工单交办处理
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetCaseResultReceiveAsync(GetCaseResultReceiveRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<GetCaseResultReceiveRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单交办处理过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetCaseProcessReceiveAsync(GetCaseProcessReceiveRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<GetCaseProcessReceiveRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单交办评价
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetVisitInfoReceiveAsync(GetVisitInfoReceiveRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<GetVisitInfoReceiveRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 退回申请
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetCaseBackApplyAsync(GetCaseBackApplyRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<GetCaseBackApplyRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单申请延时
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushDelayCaseInfoSendAsync(DelayCaseInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<DelayCaseInfoSendRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单督办过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendSuperviseProcessInfoAsync(SendSuperviseProcessInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<SendSuperviseProcessInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单督办结果
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendSuperviseResultInfoAsync(SendSuperviseResultInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<SendSuperviseResultInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 工单发起甄别接
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushScreenCaseInfoSendAsync(ScreenCaseInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<ScreenCaseInfoSendRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 政民互动提交公开
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushZMHDCaseInfoPublicAsync(ZmhdCaseInfoPublicRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<ZmhdCaseInfoPublicRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    #endregion
+
+    #region 汇聚-第二批次
+    /// <summary>
+    /// 服务工单受理
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushOrderCreatedAsync(SubmitCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitCaseInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单处理结果
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseResultAsync(SubmitCaseResultRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitCaseResultRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单处理过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseProcessAsync(SubmitCaseProcessRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitCaseProcessRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单回访评价
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitVisitInfoAsync(SubmitVisitInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitVisitInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 电话记录
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseRecordAsync(SubmitCaseRecordRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitCaseRecordRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 统计数据
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseTotalAsync(SubmitCaseTotalRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitCaseTotalRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单拓展信息
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseExtendsAsync(SubmitCaseExtendsRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SubmitCaseExtendsRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+    #endregion
+
+    #region 协同-第三批次
+    /// <summary>
+    /// 服务工单上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendCaseInfoAsync(SendCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<SendCaseInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 上报补充诉求
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSupplyCaseInfoSendAsync(SupplyCaseInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<SupplyCaseInfoSendRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单撤单
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushRevokeCaseInfoAsync(SendRevokeCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<SendRevokeCaseInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单催单
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendRemindCaseInfoAsync(SendRemindCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<SendRemindCaseInfoRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 服务工单上报12315过程信息查询
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<ProvinceDistrecordResponse> PushGetCaseDistrecordSendAsync(GetCaseDistrecordSendRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _xieTongClient.RequestAsync<GetCaseDistrecordSendRequest, ProvinceDistrecordResponse>(request, cancellationToken);
+        return response;
+    }
+    #endregion
+
+    #region 协同-第四批次
+    /// <summary>
+    /// 知识库上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetKnowledgeInfoSendAsync(GetKnowledgeInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<GetKnowledgeInfoSendRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 知识库变更
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetKnowledgeInfoUpdateAsync(GetKnowledgeInfoUpdateRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<GetKnowledgeInfoUpdateRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 知识库下架
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetKnowledgeInfoAbandonAsync(GetKnowledgeInfoAbandonRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<GetKnowledgeInfoAbandonRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    /// <summary>
+    /// 实时服务上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendRealTimeStatusAsync(SendRealTimeStatusRequest request, CancellationToken cancellationToken)
+    {
+        var response = await _huiJuClient.RequestAsync<SendRealTimeStatusRequest, ProvinceResponse>(request, cancellationToken);
+        return response?.ReturnInfo;
+    }
+
+    #endregion
+}

+ 23 - 0
src/Hotline/DataSharing/Province/HttpClientExtensions.cs

@@ -0,0 +1,23 @@
+using Hotline.DataSharing.Extensions;
+using IdentityModel.Client;
+using System.Net.Http.Headers;
+using XF.Domain.Exceptions;
+
+namespace Hotline.DataSharing.Province
+{
+    public static class HttpClientExtensions
+    {
+        public static HttpClient BuildHeader(this HttpClient httpClient, string token)
+        {
+            if (string.IsNullOrEmpty(token))
+                throw new UserFriendlyException("无效token");
+            httpClient.SetBearerToken(token);
+            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+
+            return httpClient;
+        }
+
+        public static HttpClient SetHttpClient(this HttpClient httpClient, string baseAddress, string token) =>
+            httpClient.SetBaseAddress(baseAddress).BuildHeader(token);
+    }
+}

+ 26 - 0
src/Hotline/DataSharing/Province/HuiJuClient.cs

@@ -0,0 +1,26 @@
+using Hotline.Share.Dtos.DataSharing.Province;
+using Microsoft.Extensions.DependencyInjection;
+using XF.Domain.Dependency;
+
+namespace Hotline.DataSharing.Province;
+
+public class HuiJuClient : ProvinceClient, ISingletonDependency, ISelfDependency
+{
+    private readonly IServiceScopeFactory _scopeFactory;
+
+    public HuiJuClient(IServiceScopeFactory scopeFactory) : base(scopeFactory)
+    {
+        _scopeFactory = scopeFactory;
+    }
+
+    public Task<TResponse?> RequestAsync<TRequest, TResponse>(TRequest request, CancellationToken cancellationToken)
+        where TRequest : IProvinceRequest, new()
+    {
+        using var scope = _scopeFactory.CreateScope();
+        var provider = scope.ServiceProvider;
+        var channelconfigManager = provider.GetRequiredService<IChannelConfigurationManager>();
+
+        var configProvince = channelconfigManager.GetConfigurationProvince();
+        return base.RequestAsync<TRequest, TResponse>(request, configProvince.HuiJu, configProvince, cancellationToken);
+    }
+}

+ 222 - 0
src/Hotline/DataSharing/Province/IProvincePusher.cs

@@ -0,0 +1,222 @@
+using Hotline.Share.Dtos.DataSharing.Province;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Knowledge;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Receive;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Send;
+using Sharing.Province.Dtos.HuiJu.Send;
+namespace Hotline.DataSharing.Province;
+
+/// <summary>
+/// 
+/// </summary>
+public interface IProvincePusher
+{
+    #region 协同-第一批次
+    /// <summary>
+    /// 服务工单交办处理
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetCaseResultReceiveAsync(GetCaseResultReceiveRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单交办处理过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetCaseProcessReceiveAsync(GetCaseProcessReceiveRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单交办评价
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetVisitInfoReceiveAsync(GetVisitInfoReceiveRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 退回申请
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetCaseBackApplyAsync(GetCaseBackApplyRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单申请延时
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushDelayCaseInfoSendAsync(DelayCaseInfoSendRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单督办过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSendSuperviseProcessInfoAsync(SendSuperviseProcessInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单督办结果
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSendSuperviseResultInfoAsync(SendSuperviseResultInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 工单发起甄别接
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushScreenCaseInfoSendAsync(ScreenCaseInfoSendRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 政民互动提交公开
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushZMHDCaseInfoPublicAsync(ZmhdCaseInfoPublicRequest request, CancellationToken cancellationToken);
+
+    #endregion
+
+    #region 汇聚-第二批次
+    /// <summary>
+    /// 服务工单受理
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushOrderCreatedAsync(SubmitCaseInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单处理结果
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSubmitCaseResultAsync(SubmitCaseResultRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单处理过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSubmitCaseProcessAsync(SubmitCaseProcessRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单回访评价
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSubmitVisitInfoAsync(SubmitVisitInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 电话记录
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSubmitCaseRecordAsync(SubmitCaseRecordRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 统计数据
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSubmitCaseTotalAsync(SubmitCaseTotalRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单拓展信息
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSubmitCaseExtendsAsync(SubmitCaseExtendsRequest request, CancellationToken cancellationToken);
+
+    #endregion
+
+    #region 协同-第三批次
+    /// <summary>
+    /// 服务工单上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSendCaseInfoAsync(SendCaseInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 上报补充诉求
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSupplyCaseInfoSendAsync(SupplyCaseInfoSendRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单撤单
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushRevokeCaseInfoAsync(SendRevokeCaseInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单催单
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSendRemindCaseInfoAsync(SendRemindCaseInfoRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 服务工单上报12315过程信息查询
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<ProvinceDistrecordResponse> PushGetCaseDistrecordSendAsync(GetCaseDistrecordSendRequest request, CancellationToken cancellationToken);
+    #endregion
+
+    #region 协同-第四批次
+    /// <summary>
+    /// 知识库上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetKnowledgeInfoSendAsync(GetKnowledgeInfoSendRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 知识库变更
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetKnowledgeInfoUpdateAsync(GetKnowledgeInfoUpdateRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 知识库下架
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushGetKnowledgeInfoAbandonAsync(GetKnowledgeInfoAbandonRequest request, CancellationToken cancellationToken);
+
+    /// <summary>
+    /// 实时服务上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    Task<BaseProvinceResponse> PushSendRealTimeStatusAsync(SendRealTimeStatusRequest request, CancellationToken cancellationToken);
+    #endregion
+}

+ 133 - 0
src/Hotline/DataSharing/Province/ProvinceClient.cs

@@ -0,0 +1,133 @@
+using Hotline.Share.Dtos.DataSharing.Province;
+using IdentityModel.Client;
+using Microsoft.Extensions.DependencyInjection;
+using System.Net.Http.Headers;
+using XF.Domain.Cache;
+using XF.Domain.Exceptions;
+
+namespace Hotline.DataSharing.Province
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public abstract class ProvinceClient //: ISingletonDependency, ISelfDependency
+    {
+        private static readonly string KeyToken = "KeyToken";
+        private readonly IServiceScopeFactory _scopeFactory;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="scopeFactory"></param>
+        public ProvinceClient(IServiceScopeFactory scopeFactory)
+        {
+            _scopeFactory = scopeFactory;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="TRequest"></typeparam>
+        /// <typeparam name="TResponse"></typeparam>
+        /// <param name="request"></param>
+        /// <param name="baseAddress"></param>
+        /// <param name="configProvince"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task<TResponse?> RequestAsync<TRequest, TResponse>(
+            TRequest request,
+            string baseAddress,
+            ConfigurationProvince configProvince,
+            CancellationToken cancellationToken)
+            where TRequest : IProvinceRequest, new()
+        {
+            using var scope = _scopeFactory.CreateScope();
+            var provider = scope.ServiceProvider;
+            //var channelconfigManager = provider.GetRequiredService<IChannelConfigurationManager>();
+            var httpInvoker = provider.GetRequiredService<IHttpInvoker>();
+            var cacheToken = provider.GetRequiredService<ITypedCache<TokenInfo>>();
+
+            //不同的批次获取TOKEN的地址不一样
+            string cacheKey = "";
+            if (baseAddress == configProvince.HuiJu)
+                cacheKey = KeyToken + "_HuiJu";
+            else
+                cacheKey = KeyToken + "_XieTong";
+
+            var token = cacheToken.GetOrSet(cacheKey,
+                d => GetTokenAsync(baseAddress, cancellationToken).GetAwaiter().GetResult(),
+                TimeSpan.FromMinutes(28));
+            //var configProvince = channelconfigManager.GetConfigurationProvince();
+            request.BuildClientInfo(configProvince.ClientId, configProvince.ClientSecret);
+
+            //todo token失效重新获取token再次请求,返回参数缺少该状态,暂无法处理
+
+            return await httpInvoker.RequestAsync<TRequest, TResponse>(request,
+                d => d.SetHttpClient(baseAddress, token?.AccessToken ?? string.Empty),
+                cancellationToken);
+        }
+
+        /// <summary>
+        /// 附件获取Token
+        /// </summary>
+        /// <param name="baseAddress"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task<TokenInfo> GetToken(string baseAddress, CancellationToken cancellationToken)
+        {
+            using var scope = _scopeFactory.CreateScope();
+            var provider = scope.ServiceProvider;
+            var cacheToken = provider.GetRequiredService<ITypedCache<TokenInfo>>();
+            string cacheKey = KeyToken + "_XieTong";
+
+            var token = cacheToken.GetOrSet(cacheKey,
+                d => GetTokenAsync(baseAddress, cancellationToken).GetAwaiter().GetResult(),
+                TimeSpan.FromMinutes(28));
+            return token;
+        }
+
+        /// <summary>
+        /// 获取token
+        /// </summary>
+        /// <param name="baseAddress"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        /// <exception cref="UserFriendlyException"></exception>
+        private async Task<TokenInfo> GetTokenAsync(string baseAddress, CancellationToken cancellationToken)
+        {
+            using var scope = _scopeFactory.CreateScope();
+            var provider = scope.ServiceProvider;
+            var channelconfigManager = provider.GetRequiredService<IChannelConfigurationManager>();
+            var httpInvoker = provider.GetRequiredService<IHttpInvoker>();
+
+            var configProvince = channelconfigManager.GetConfigurationProvince();
+            //   var baseAddress = baseAddress;// configProvince.XieTong;// configProvince.HuiJu;
+            if (!baseAddress.EndsWith('/'))
+                baseAddress += "/";
+            var request = new ClientCredentialsTokenRequest
+            {
+                ClientId = configProvince.ClientId,
+                ClientSecret = configProvince.ClientSecret,
+                Address = $"{baseAddress}oauth2/token",
+                Headers =
+                {
+                    Accept =
+                    {
+                        MediaTypeWithQualityHeaderValue.Parse("application/x-www-form-urlencoded")
+                    }
+                }
+
+            };
+            var tokenResponse = await httpInvoker.GetTokenAsync(request, cancellationToken);
+            if (tokenResponse is null)
+                throw new UserFriendlyException("获取token请求失败");
+            if (tokenResponse.IsError)
+                throw new UserFriendlyException("获取token请求失败");
+
+            var tokenInfo = System.Text.Json.JsonSerializer.Deserialize<TokenRsp>(tokenResponse.Raw);
+            if (tokenInfo?.TokenInfo is null)
+                throw new UserFriendlyException("token解析失败");
+            return tokenInfo.TokenInfo;
+        }
+    }
+}

+ 26 - 0
src/Hotline/DataSharing/Province/PusherProvider.cs

@@ -0,0 +1,26 @@
+using XF.Domain.Dependency;
+
+namespace Hotline.DataSharing.Province;
+
+public class PusherProvider : IScopeDependency, ISelfDependency
+{
+    private readonly HuiJuClient _huiJuClient;
+    private readonly XieTongClient _xieTongClient;
+
+    public PusherProvider(HuiJuClient huiJuClient, XieTongClient xieTongClient)
+    {
+        _huiJuClient = huiJuClient;
+        _xieTongClient = xieTongClient;
+    }
+
+    public IProvincePusher CreatePusher(IChannelConfigurationManager channelConfigurationManager)
+    {
+        var configProvince = channelConfigurationManager.GetConfigurationProvince();
+        return configProvince.Scheme switch
+        {
+            ConfigurationConsts.SchemeDefault => new DefaultPusher(_huiJuClient, _xieTongClient),
+            ConfigurationConsts.SchemeSmart => new SmartPusher(),
+            _ => new DefaultPusher(_huiJuClient, _xieTongClient)
+        };
+    }
+}

+ 297 - 0
src/Hotline/DataSharing/Province/SmartPusher.cs

@@ -0,0 +1,297 @@
+using Hotline.Share.Dtos.DataSharing.Province;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Knowledge;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Receive;
+using Hotline.Share.Dtos.DataSharing.Province.XieTong.Send;
+using Sharing.Province.Dtos.HuiJu.Send;
+
+namespace Hotline.DataSharing.Province;
+
+/// <summary>
+/// todo 留待扩展
+/// </summary>
+public class SmartPusher : IProvincePusher
+{
+    #region 协同-第一批次
+    /// <summary>
+    /// 服务工单交办处理
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetCaseResultReceiveAsync(GetCaseResultReceiveRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单交办处理过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetCaseProcessReceiveAsync(GetCaseProcessReceiveRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单交办评价
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetVisitInfoReceiveAsync(GetVisitInfoReceiveRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 退回申请
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetCaseBackApplyAsync(GetCaseBackApplyRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单申请延时
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushDelayCaseInfoSendAsync(DelayCaseInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单督办过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendSuperviseProcessInfoAsync(SendSuperviseProcessInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单督办结果
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendSuperviseResultInfoAsync(SendSuperviseResultInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 工单发起甄别接
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushScreenCaseInfoSendAsync(ScreenCaseInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 政民互动提交公开
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushZMHDCaseInfoPublicAsync(ZmhdCaseInfoPublicRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+    #endregion
+
+    #region 汇聚-第二批次
+    /// <summary>
+    /// 服务工单受理
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public async Task<BaseProvinceResponse> PushOrderCreatedAsync(SubmitCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单处理结果
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseResultAsync(SubmitCaseResultRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单处理过程
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseProcessAsync(SubmitCaseProcessRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单回访评价
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitVisitInfoAsync(SubmitVisitInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 电话记录
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseRecordAsync(SubmitCaseRecordRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 统计数据
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseTotalAsync(SubmitCaseTotalRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单拓展信息
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSubmitCaseExtendsAsync(SubmitCaseExtendsRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+    #endregion
+
+    #region 协同-第三批次
+    /// <summary>
+    /// 服务工单上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendCaseInfoAsync(SendCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 上报补充诉求
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSupplyCaseInfoSendAsync(SupplyCaseInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单撤单
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushRevokeCaseInfoAsync(SendRevokeCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单催单
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendRemindCaseInfoAsync(SendRemindCaseInfoRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 服务工单上报12315过程信息查询
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<ProvinceDistrecordResponse> PushGetCaseDistrecordSendAsync(GetCaseDistrecordSendRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+    #endregion
+
+    #region 协同-第四批次
+    /// <summary>
+    /// 知识库上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetKnowledgeInfoSendAsync(GetKnowledgeInfoSendRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 知识库变更
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetKnowledgeInfoUpdateAsync(GetKnowledgeInfoUpdateRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 知识库下架
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushGetKnowledgeInfoAbandonAsync(GetKnowledgeInfoAbandonRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    /// 实时服务上报
+    /// </summary>
+    /// <param name="request"></param>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<BaseProvinceResponse> PushSendRealTimeStatusAsync(SendRealTimeStatusRequest request, CancellationToken cancellationToken)
+    {
+        throw new NotImplementedException();
+    }
+    #endregion
+}

+ 42 - 0
src/Hotline/DataSharing/Province/XieTongClient.cs

@@ -0,0 +1,42 @@
+using Hotline.Share.Dtos.DataSharing.Province;
+using Microsoft.Extensions.DependencyInjection;
+using XF.Domain.Dependency;
+
+namespace Hotline.DataSharing.Province;
+
+public class XieTongClient : ProvinceClient, ISingletonDependency, ISelfDependency
+{
+    private readonly IServiceScopeFactory _scopeFactory;
+
+    public XieTongClient(IServiceScopeFactory scopeFactory) : base(scopeFactory)
+    {
+        _scopeFactory = scopeFactory;
+    }
+
+    public Task<TResponse?> RequestAsync<TRequest, TResponse>(TRequest request, CancellationToken cancellationToken)
+        where TRequest : IProvinceRequest, new()
+    {
+        using var scope = _scopeFactory.CreateScope();
+        var provider = scope.ServiceProvider;
+        var channelconfigManager = provider.GetRequiredService<IChannelConfigurationManager>();
+
+        var configProvince = channelconfigManager.GetConfigurationProvince();
+        return base.RequestAsync<TRequest, TResponse>(request, configProvince.XieTong, configProvince, cancellationToken);
+    }
+
+    /// <summary>
+    /// 附件获取Token
+    /// </summary>
+    /// <param name="cancellationToken"></param>
+    /// <returns></returns>
+    public async Task<string> GetTokenAsync(CancellationToken cancellationToken)
+    {
+        using var scope = _scopeFactory.CreateScope();
+        var provider = scope.ServiceProvider;
+        var channelconfigManager = provider.GetRequiredService<IChannelConfigurationManager>();
+
+        var configProvince = channelconfigManager.GetConfigurationProvince();
+        var token = await GetToken(configProvince.XieTong, cancellationToken);
+        return token?.AccessToken ?? string.Empty;
+    }
+}