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 logger, [FromKeyedServices(HttpEnum.Hyd)] IRestClient client) { this.caching = caching; this.client = client; //logger = logFactory.CreateLogger("BigDataLogger"); this.logger = logger; } public async Task Submit(HydSubmitDto submitDto, bool isRetry = true) { try { string token = await GetToken(); var url = AppSettings.app("Apis", "Hyd", "SubmitUrl"); var customer = AppSettings.app("Apis", "Hyd", "CUSTOMER"); var headers = new Dictionary() { { "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 (isRetry) { return await Submit(submitDto, false); } } throw new Exception($"code:{code},msg:{msg}"); } } catch (Exception ex) { throw new Exception($"下单或开发票失败,原因:{DealExMessage(ex?.Message)}"); } } public async Task> 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() { { "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>(jobj.GetValue("rows").ToString()); return result; } else { if (code > 400 && code < 500) { await caching.DelCacheKeyAsync(CacheConst.HydAccessToken); } } } throw new Exception("调用外部状态查询接口失败"); } public async Task FeedBack(List hydFeedbackDtoList, bool isRetry = true) { try { string token = await GetToken(); var url = AppSettings.app("Apis", "Hyd", "FeedbackUrl"); var customer = AppSettings.app("Apis", "Hyd", "CUSTOMER"); var headers = new Dictionary() { { "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 (isRetry) { return await FeedBack(hydFeedbackDtoList, false); } } throw new Exception($"code:{code},msg:{msg}"); } } return true; } catch (Exception ex) { throw new Exception($"反馈失败,原因:{DealExMessage(ex?.Message)}"); } } private async Task GetToken() { try { var token = await caching.GetAsync(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("海运达", "")}"; } } } }