using EntrustSettle.Common; using EntrustSettle.Controllers; using EntrustSettle.IServices; using EntrustSettle.Model; using EntrustSettle.Model.Dtos; using EntrustSettle.Model.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using RestSharp; namespace EntrustSettle.Api.Controllers { /// /// 对外提供的委托结算相关接口 /// [AllowAnonymous] public class OpenController : BaseApiController { private readonly IOrderService orderService; private readonly IAnnexService annexService; private readonly IOrderAnnexService orderAnnexService; private readonly ILogger logger; private readonly IOrderHistoryService orderHistoryService; private readonly IQueueService queueService; private readonly IOrderFeeService orderFeeService; public OpenController(IOrderService orderService, ILogger logger, IOrderHistoryService orderHistoryService, IQueueService queueService, IOrderFeeService orderFeeService, IAnnexService annexService, IOrderAnnexService orderAnnexService) { this.orderService = orderService; this.logger = logger; this.orderHistoryService = orderHistoryService; this.queueService = queueService; this.orderFeeService = orderFeeService; this.annexService = annexService; this.orderAnnexService = orderAnnexService; } /// /// 下单 /// [HttpPost] [ApiUser(ApiCode = "EntrustSettle")] public async Task>> OrderSubmit(OrderSubmitDto inputDto) { var result = await App.GetService().Submit(inputDto); return result; } /// /// 附件上传 /// /// 附件文件 /// 文件类型 [HttpPost] [ApiUser(ApiCode = "EntrustSettle")] public async Task> AnnexUpload([FromForm] IFormFile file, [FromForm] FileTypeEnum fileType) { var result = await App.GetService().Upload(file, fileType); return result; } /// /// 反馈信息(为订单追加附件或信息) /// /// [HttpPost] [ApiUser(ApiCode = "EntrustSettle")] public async Task BindAnnexOrInfo([FromBody] BindAnnexOrInfoDto bindDto) { var result = await App.GetService().BindAnnexOrInfo(bindDto); return result; } /// /// 获取附件 /// /// 文件记录主键 [HttpGet] [ApiUser(ApiCode = "EntrustSettle")] public async Task AnnexDownload([FromQuery] long annexId) { var result = await App.GetService().DownloadFile(annexId); return result; } /// /// 海运达状态回推接口 /// [HttpPost] [ApiUser(ApiCode = "PushOrderStatus")] public async Task PushOrderStatus([FromBody] HydQueryResultDto input) { var orderList = await orderService.Query(x => x.Bsno == input.id); if (orderList == null || orderList.Count == 0) { string msg = $"订单Id[{input.id}]接收到回推后未查询到本地订单"; logger.LogInformation(msg); return FailedMsg(msg); } if (orderList.Count > 1) { string msg = $"订单Id[{input.id}]接收到回推后根据Id查询到多个本地订单:{string.Join(',', orderList.Select(x => x.Mblno))}"; logger.LogInformation(msg); return FailedMsg(msg); } var order = orderList[0]; // 保存往来单据 if (input.feedbackList != null && input.feedbackList.Count > 0) { var outerFileIdList = input.feedbackList.Select(x => x.id).ToList(); var existsOuterFileIdList = await orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == order.Id && outerFileIdList.Contains((long)a.OuterFileId)) .Select((o, a) => a.OuterFileId) .ToListAsync(); foreach (var item in input.feedbackList) { // 如果文件不是外部推送的,不处理 if (item.sendType != 1) continue; // 如果文件信息已经存在,不处理 if (existsOuterFileIdList.Contains(item.id)) continue; if (!string.IsNullOrEmpty(item.fileUrl)) { // 检查文件保存目录 var dir = Path.Combine(App.WebHostEnvironment.WebRootPath, "files"); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } // 文件名 var newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(item.fileName); // 相对路径 var relativePath = Path.Combine("files", newFileName); // 完整路径 var fullPath = Path.Combine(dir, newFileName); // 保存附件信息 var annex = new Annex() { Type = 5, OuterFileId = item.id, Name = item.fileName, Remark = item.remark, BusinessTime = item.createTime, Path = relativePath }; await annexService.Add(annex); var orderAnnex = new OrderAnnex() { OrderId = order.Id, AnnexId = annex.Id }; await orderAnnexService.Add(orderAnnex); var restClient = new RestClient(item.fileUrl); var request = new RestRequest(); using var stream = await restClient.DownloadStreamAsync(request); using FileStream fileStream = new FileStream(fullPath, FileMode.Create); await stream.CopyToAsync(fileStream); } } } // 将更新后的状态及费用推送到消息队列 if (AppSettings.app("RabbitMQ", "Enabled").ObjToBool()) { string msg = $"Id:[{order.Id}],提单号[{order.Mblno}],自动更新状态后推送队列"; _ = Task.Run(() => { try { StatusPushDto pushDto = new() { OrderId = order.Id, Mblno = order.Mblno, MessageType = 1, MessageDesc = "状态更新推送", Remark = "", Status = input.status, StatusDesc = input.status switch { 0 => "已下单", 1 => "已接单", 2 => "待缴费", 3 => "已缴费", 4 => "已完结", _ => "未知状态", } }; var feeList = orderFeeService.AsQueryable().Where(x => x.OrderId == order.Id).ToList(); if (feeList.Count > 0) { pushDto.FeeList = feeList.Select(x => new StatusPushDto.FeeDto() { FeeId = x.Id, FeeName = x.Name, FeeAmount = x.Amount }).ToList(); } var annexList = orderAnnexService.AsQueryable() .LeftJoin((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == order.Id && a.Type == 5) .Select((o, a) => a) .ToList(); if (annexList.Count > 0) { pushDto.FeebackAnnexList = annexList.Select(x => new StatusPushDto.FeebackAnnex() { Id = x.Id, BusinessTime = x.BusinessTime, FileName = x.Name, Remark = x.Remark }).ToList(); } var json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); queueService.Push(msg, order.CompanyId, json); } catch (Exception ex) { logger.LogError(ex, $"订单Id[{input.id}],提单号[{order.Mblno}]接收到状态然后推送时发生未知异常:{msg}"); } }); } if (order.Status != input.status) { order.Status = input.status; var updateSuccess = await orderService.Update(order, x => new { x.Status }); logger.LogInformation($"订单Id[{input.id}],提单号[{order.Mblno}]状态更新{(updateSuccess ? "成功" : "失败")},status:{input.status}"); // 记录订单状态变更历史 await orderHistoryService.Add(new OrderHistory() { Pid = order.Id, Status = input.status, StatusTime = DateTime.Now, CreateBy = "系统", Remark = "(状态接收)" }); return SuccessMsg($"订单Id[{input.id}],提单号[{order.Mblno}]状态更新成功"); } else { string msg = $"订单Id[{input.id}],提单号[{order.Mblno}]状态不变"; logger.LogInformation(msg); return SuccessMsg(msg); } } } }