You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
9.4 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using EntrustSettle.Common;
using EntrustSettle.Common.Caches;
using EntrustSettle.Common.Const;
using EntrustSettle.IServices;
using EntrustSettle.Model;
using EntrustSettle.Model.Dtos;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace EntrustSettle.Services
{
public class HYDService : IHYDService
{
private const string HYD_LOGIN_ERROR_MSG1 = "重新登录";
private const string HYD_LOGIN_ERROR_MSG2 = "token";
private readonly ICaching caching;
private readonly ILogger logger;
private readonly IRestClient client;
public HYDService(ICaching caching,
//ILoggerFactory logFactory,
ILogger<HYDService> logger,
[FromKeyedServices(HttpEnum.Hyd)] IRestClient client)
{
this.caching = caching;
this.client = client;
//logger = logFactory.CreateLogger("BigDataLogger");
this.logger = logger;
}
public async Task<long> Submit(HydSubmitDto submitDto, int retryTimes = 2)
{
try
{
string token = await GetToken();
var url = AppSettings.app("Apis", "Hyd", "SubmitUrl");
var customer = AppSettings.app("Apis", "Hyd", "CUSTOMER");
var headers = new Dictionary<string, string>()
{
{ "PDK", token },
{ "CUSTOMER", customer }
};
var request = new RestRequest(url);
request.AddHeaders(headers);
request.AddJsonBody(submitDto);
var resp = await client.PostAsync(request); // 以Execute开头的方法不会引发异常
logger.LogRestSharp("海运达下单接口", client, request, resp);
var jobj = JObject.Parse(resp.Content);
var code = jobj.GetValue("code").ObjToInt();
if (code == 200)
{
var bsno = jobj.GetValue("data").ObjToLong();
return bsno;
}
else
{
var msg = jobj.GetValue("msg").ToString();
if ((code > 400 && code < 500) || msg.Contains(HYD_LOGIN_ERROR_MSG1) || msg.Contains(HYD_LOGIN_ERROR_MSG2))
{
await caching.RemoveAsync(CacheConst.HydAccessToken);
if (retryTimes > 0)
{
logger.LogRestSharp($"海运达下单接口时发生Token失效问题剩余重试次数{retryTimes},开始重试", client, request, resp);
retryTimes--;
return await Submit(submitDto, retryTimes);
}
}
throw new Exception($"code:{code},msg:{msg}");
}
}
catch (Exception ex)
{
throw new Exception($"下单或开发票失败,原因:{DealExMessage(ex?.Message)}");
}
}
public async Task<List<HydQueryResultDto>> Query(string mblno)
{
string token = await GetToken();
var url = AppSettings.app("Apis", "Hyd", "QueryUrl");
var customer = AppSettings.app("Apis", "Hyd", "CUSTOMER");
var headers = new Dictionary<string, string>()
{
{ "PDK", token },
{ "CUSTOMER", customer }
};
string[] param = [mblno];
var request = new RestRequest(url);
request.AddHeaders(headers);
request.AddJsonBody(param);
var resp = await client.ExecuteGetAsync(request); // 以Execute开头的方法不会引发异常
logger.LogRestSharp("海运达状态查询接口", client, request, resp);
if (resp.IsSuccessful)
{
var jobj = JObject.Parse(resp.Content);
var code = jobj.GetValue("code").ObjToInt();
if (code == 200)
{
var result = JsonConvert.DeserializeObject<List<HydQueryResultDto>>(jobj.GetValue("rows").ToString());
return result;
}
else
{
if (code > 400 && code < 500)
{
await caching.DelCacheKeyAsync(CacheConst.HydAccessToken);
}
}
}
throw new Exception("调用外部状态查询接口失败");
}
public async Task<bool> FeedBack(List<HydFeedbackDto> hydFeedbackDtoList, int retryTimes = 2)
{
try
{
string token = await GetToken();
var url = AppSettings.app("Apis", "Hyd", "FeedbackUrl");
var customer = AppSettings.app("Apis", "Hyd", "CUSTOMER");
var headers = new Dictionary<string, string>()
{
{ "PDK", token },
{ "CUSTOMER", customer }
};
foreach (var item in hydFeedbackDtoList)
{
var request = new RestRequest(url);
request.AddHeaders(headers);
request.AddJsonBody(item);
var resp = await client.PostAsync(request); // 以Execute开头的方法不会引发异常
logger.LogRestSharp("海运达反馈接口", client, request, resp);
//var jobj = JObject.Parse("{\"msg\":\"token格式/信息有误,或账号已在其他系统登录,请重新登录\",\"code\":500}");
var jobj = JObject.Parse(resp.Content);
var code = jobj.GetValue("code").ObjToInt();
if (code == 200)
{
continue;
}
else
{
var msg = jobj.GetValue("msg").ToString();
if ((code > 400 && code < 500) || msg.Contains(HYD_LOGIN_ERROR_MSG1) || msg.Contains(HYD_LOGIN_ERROR_MSG2))
{
await caching.RemoveAsync(CacheConst.HydAccessToken);
if (retryTimes > 0)
{
logger.LogRestSharp($"海运达反馈接口时发生Token失效问题剩余重试次数{retryTimes},开始重试", client, request, resp);
retryTimes--;
return await FeedBack(hydFeedbackDtoList, retryTimes);
}
}
throw new Exception($"code:{code},msg:{msg}");
}
}
return true;
}
catch (Exception ex)
{
throw new Exception($"反馈失败,原因:{DealExMessage(ex?.Message)}");
}
}
private async Task<string> GetToken()
{
try
{
var token = await caching.GetAsync<string>(CacheConst.HydAccessToken);
if (!string.IsNullOrEmpty(token))
{
return token;
}
var url = AppSettings.app("Apis", "Hyd", "LoginUrl");
var request = new RestRequest(url);
var body = new
{
username = AppSettings.app("Apis", "Hyd", "username"),
password = AppSettings.app("Apis", "Hyd", "password")
};
request.AddJsonBody(body);
var resp = await client.PostAsync(request); // 以Execute开头的方法不会引发异常
logger.LogRestSharp("海运达登录接口", client, request, resp);
var jobj = JObject.Parse(resp.Content);
var code = jobj.GetValue("code");
if (code.ObjToInt() == 200)
{
token = jobj.GetValue("token").ToString();
await caching.SetAsync(CacheConst.HydAccessToken, token, TimeSpan.FromSeconds(AppSettings.app("Apis", "Hyd", "TokenCacheTime").ObjToInt()));
return token;
}
else
{
var msg = jobj.GetValue("msg");
throw new Exception($"code:{code},msg:{msg}");
}
}
catch (Exception ex)
{
throw new Exception($"调用外部登录接口时发生异常({DealExMessage(ex?.Message)}");
}
}
string DealExMessage(string msg)
{
if (msg == null)
{
return null;
}
// 添加判断,防止暴露海运达的接口地址给使用方
if (msg.Contains("不知道这样的主机"))
{
return "无法连接到外部主机请检查连接状态如果当前为测试环境请检查VPN";
}
else
{
return $"{msg.Replace("sdlandsea", "").Replace("sdland-sea", "").Replace("", "")}";
}
}
}
}