using Furion.FriendlyException; using Furion.JsonSerialization; using Furion; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Furion.RemoteRequest.Extensions; using Furion.DependencyInjection; using Microsoft.AspNetCore.Mvc; using System.Xml.Linq; using Furion.DynamicApiController; using Microsoft.AspNetCore.Authorization; using Myshipping.Application.Entity; using Myshipping.Core; using Furion.DistributedIDGenerator; using Mapster; using Furion.DataValidation; using Newtonsoft.Json.Linq; namespace Myshipping.Application { /// /// 请求规则平台 /// [ApiDescriptionSettings("Application", Name = "RulesEngineClient", Order = 9)] public class RulesEngineClientService: IRulesEngineClientService, IDynamicApiController, ITransient { private readonly SqlSugarRepository _bookingOrderRepository; private readonly SqlSugarRepository _bookingOrderContaRepository; private readonly SqlSugarRepository _bookingOrderContaCargoRepository; /// /// /// public RulesEngineClientService(SqlSugarRepository bookingOrderRepository, SqlSugarRepository bookingOrderContaRepository, SqlSugarRepository bookingOrderContaCargoRepository) { _bookingOrderRepository = bookingOrderRepository; _bookingOrderContaRepository = bookingOrderContaRepository; _bookingOrderContaCargoRepository = bookingOrderContaCargoRepository; } #region 海运订舱请求规则引擎校验 /// /// 海运订舱请求规则引擎校验 /// /// 海运订舱请求业务 /// 返回用户信息 [HttpPost("/RulesEngineClient/ExcuteRulesOceanBookingByMsg")] public async Task ExcuteRulesOceanBookingByMsg(RulesEngineOrderBookingMessageInfo model) { RulesEngineExcuteResultDto result = new RulesEngineExcuteResultDto(); var ruleResult = await ExcuteRulesEngine(model); if (ruleResult == null) throw Oops.Oh($"订舱请求规则失败,返回为空"); var innerRlt = JSON.Deserialize(ruleResult.extra.ToString()); var ruleDetailList = innerRlt.DetailList; result.succ = ruleResult.succ; result.msg = ruleResult.msg; if (ruleDetailList.Count > 0) { result.rows = ruleDetailList; } return result; } #endregion #region 海运订舱请求规则引擎校验 /// /// 海运订舱请求规则引擎校验 /// /// 海运订舱主键 /// 返回用户信息 [HttpGet("/RulesEngineClient/ExcuteRulesOceanBooking")] public async Task ExcuteRulesOceanBooking(string bookingId) { /* 处理逻辑 1、订单保存后触发调取此方法,传入海运订舱主键。 2、调取订舱的详情。 3、对应请求报文。 4、请求规则接口。 5、返回回执。 */ RulesEngineExcuteResultDto result = new RulesEngineExcuteResultDto(); try { DateTime nowDate = DateTime.Now; var model = _bookingOrderRepository.AsQueryable().InSingle(long.Parse(bookingId)); if (model == null) throw Oops.Oh($"订舱主键{bookingId}无法获取业务信息"); RulesEngineOrderBookingMessageInfo msgModel = new RulesEngineOrderBookingMessageInfo(); msgModel.Head = new RulesEngineWebAPIHeadBase { GID = IDGen.NextID().ToString(), MessageType = "BUSI_RULE", SenderId = App.Configuration["RulesEngineSender"], SenderName = App.Configuration["RulesEngineSenderName"], SenderKey = App.Configuration["RulesEngineAuthKey"], ReceiverId = "RulesEngine", ReceiverName = "大简云规则引擎", Version = "1.0", RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), RequestAction = "CheckRule", }; msgModel.Main = new RulesEngineOrderBookingMainInfo { ProjectCode = App.Configuration["RulesEngineProjects"].Split(new char[] { ','}).ToArray(), }; msgModel.Main.BusinessInfo = model.Adapt(); var contaList = await _bookingOrderContaRepository.AsQueryable().Where(x => x.BILLID == model.Id).ToListAsync(); if (contaList.Count > 0) { msgModel.Main.BusinessInfo.ContaList = contaList.Adapt>(); var ctnArg = contaList.Select(t => t.Id).ToArray(); var cargoList = await _bookingOrderContaCargoRepository.AsQueryable() .Where(x=> ctnArg.Contains(x.CTNID.Value)).ToListAsync(); if(cargoList.Count > 0) { msgModel.Main.BusinessInfo.ContaList = contaList.GroupJoin(cargoList, l => l.Id, r => r.CTNID, (l, r) => { var currList = r.ToList(); if (currList.Count > 0) { var info = l.Adapt(); info.CargoList = currList.Adapt>(); return info; } return l.Adapt(); }).ToList(); } else { msgModel.Main.BusinessInfo.ContaList = contaList.Adapt>(); } } var ruleResult = await ExcuteRulesEngine(msgModel); if(ruleResult == null) throw Oops.Oh($"订舱主键{bookingId}请求规则失败,返回为空"); var innerRlt = JSON.Deserialize(ruleResult.extra.ToString()); var ruleDetailList = innerRlt.DetailList; result.succ = ruleResult.succ; result.msg = ruleResult.msg; if (ruleDetailList != null && ruleDetailList.Count > 0) { result.rows = ruleDetailList; } } catch(Exception ex) { result.succ = false; result.msg = "请求规则异常"; } return result; } #endregion #region 海运订舱请求规则引擎校验 /// /// 海运订舱请求规则引擎校验 /// /// 海运订舱报文类 /// 返回回执 [HttpPost("/RulesEngineClient/ExcuteRulesOceanBookingByModel")] public async Task ExcuteRulesOceanBookingByModel(BookingOrderDto model) { /* 处理逻辑 1、前台将保存报文推送过来。 2、如果有订舱主键调取数据库内的订舱的详情,已推送的数据为准。 3、对应请求报文。 4、请求规则接口。 5、返回回执。 */ RulesEngineExcuteResultDto result = new RulesEngineExcuteResultDto(); try { DateTime nowDate = DateTime.Now; //var model = //if() // _bookingOrderRepository.AsQueryable().InSingle(bookingId); //if (model == null) // throw Oops.Oh($"订舱主键{bookingId}无法获取业务信息"); RulesEngineOrderBookingMessageInfo msgModel = new RulesEngineOrderBookingMessageInfo(); msgModel.Head = new RulesEngineWebAPIHeadBase { GID = IDGen.NextID().ToString(), MessageType = "BUSI_RULE", SenderId = App.Configuration["RulesEngineSender"], SenderName = App.Configuration["RulesEngineSenderName"], SenderKey = App.Configuration["RulesEngineAuthKey"], ReceiverId = "RulesEngine", ReceiverName = "大简云规则引擎", Version = "1.0", RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"), RequestAction = "CheckRule", }; msgModel.Main = new RulesEngineOrderBookingMainInfo { ProjectCode = App.Configuration["RulesEngineProjects"].Split(new char[] { ',' }).ToArray(), }; msgModel.Main.BusinessInfo = model.Adapt(); var contaList = await _bookingOrderContaRepository.AsQueryable().Where(x => x.BILLID == model.Id).ToListAsync(); if (contaList.Count > 0) { msgModel.Main.BusinessInfo.ContaList = contaList.Adapt>(); var cargoList = await _bookingOrderContaCargoRepository.AsQueryable() .Where(x => contaList.Any(a => a.Id == x.CTNID)).ToListAsync(); if (cargoList.Count > 0) { msgModel.Main.BusinessInfo.ContaList = contaList.GroupJoin(cargoList, l => l.Id, r => r.CTNID, (l, r) => { var currList = r.ToList(); if (currList.Count > 0) { var info = l.Adapt(); info.CargoList = currList.Adapt>(); return info; } return l.Adapt(); }).ToList(); } else { msgModel.Main.BusinessInfo.ContaList = contaList.Adapt>(); } } var ruleResult = await ExcuteRulesEngine(msgModel); if (ruleResult == null) throw Oops.Oh($"订舱主键{model.BOOKINGNO}请求规则失败,返回为空"); var innerRlt = JSON.Deserialize(ruleResult.extra.ToString()); var ruleDetailList = innerRlt.DetailList; result.succ = ruleResult.succ; result.msg = ruleResult.msg; if (ruleDetailList.Count > 0) { result.rows = ruleDetailList; } } catch (Exception ex) { result.succ = false; result.msg = "请求规则异常"; } return result; } #endregion #region 请求规则平台 /// /// 请求规则平台 /// /// /// private async Task ExcuteRulesEngine(RulesEngineOrderBookingMessageInfo info) { RulesEngineWebApiResult model = null; /* 1、读取配置文件中的规则引擎URL 2、填充请求的类,并生成JSON报文 3、POST请求接口,并记录回执。 4、返回信息。 */ var url = App.Configuration["RulesEngineUrl"]; try { var res = await url.SetHttpMethod(HttpMethod.Post) .SetBody(JSON.Serialize(info), "application/json") .SetContentEncoding(Encoding.UTF8) .PostAsync(); if (res.StatusCode == System.Net.HttpStatusCode.OK) { var userResult = await res.Content.ReadAsStringAsync(); model = JSON.Deserialize(userResult); } } catch (Exception ex) { //写日志 if (ex is HttpRequestException) throw Oops.Oh(10000002); } return model; } #endregion } }