From 71f5daf382301296935bd3be910efa822bcdd84e Mon Sep 17 00:00:00 2001 From: zhangxiaofeng <1939543722@qq.com> Date: Tue, 30 Apr 2024 10:14:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=8E=A5=E6=94=B6=E5=8F=8A?= =?UTF-8?q?=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/OpenController.cs | 147 ++++++++++++++---- .../Controllers/OrderController.cs | 31 +++- EntrustSettle.Api/Program.cs | 12 ++ .../CustomEnums/BusinessEnums.cs | 3 +- .../Dtos/Hyd/HydQueryResultDto.cs | 35 ++++- .../Dtos/Queue/StatusPushDto.cs | 31 +++- EntrustSettle.Model/Models/Annex.cs | 15 +- EntrustSettle.Services/QueueService.cs | 2 +- .../QuartzNet/Jobs/JobHydSubmitQuartz.cs | 2 +- 9 files changed, 238 insertions(+), 40 deletions(-) diff --git a/EntrustSettle.Api/Controllers/OpenController.cs b/EntrustSettle.Api/Controllers/OpenController.cs index d761db8..bfa5e05 100644 --- a/EntrustSettle.Api/Controllers/OpenController.cs +++ b/EntrustSettle.Api/Controllers/OpenController.cs @@ -7,6 +7,7 @@ using EntrustSettle.Model.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; +using RestSharp; namespace EntrustSettle.Api.Controllers { @@ -17,6 +18,8 @@ namespace EntrustSettle.Api.Controllers 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; @@ -25,13 +28,17 @@ namespace EntrustSettle.Api.Controllers ILogger logger, IOrderHistoryService orderHistoryService, IQueueService queueService, - IOrderFeeService orderFeeService) + 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; } /// @@ -87,41 +94,90 @@ namespace EntrustSettle.Api.Controllers /// [HttpPost] [ApiUser(ApiCode = "PushOrderStatus")] - public async Task PushOrderStatus([FromBody] HydQueryResultDto item) + public async Task PushOrderStatus([FromBody] HydQueryResultDto input) { - var orderList = await orderService.Query(x => x.Bsno == item.id); + var orderList = await orderService.Query(x => x.Bsno == input.id); if (orderList == null || orderList.Count == 0) { - string msg = $"订单Id[{item.id}]接收到回推后未查询到本地订单"; + string msg = $"订单Id[{input.id}]接收到回推后未查询到本地订单"; logger.LogInformation(msg); return FailedMsg(msg); } if (orderList.Count > 1) { - string msg = $"订单Id[{item.id}]接收到回推后根据Id查询到多个本地订单:{string.Join(',', orderList.Select(x => x.Mblno))}"; + string msg = $"订单Id[{input.id}]接收到回推后根据Id查询到多个本地订单:{string.Join(',', orderList.Select(x => x.Mblno))}"; logger.LogInformation(msg); return FailedMsg(msg); } var order = orderList[0]; - if (order.Status == item.status) - { - string msg = $"订单Id[{item.id}],提单号[{order.Mblno}]状态不变"; - logger.LogInformation(msg); - return SuccessMsg(msg); - } - order.Status = item.status; - var updateSuccess = await orderService.Update(order, x => new { x.Status }); - logger.LogInformation($"订单Id[{item.id}],提单号[{order.Mblno}]状态更新{(updateSuccess ? "成功" : "失败")},status:{item.status}"); - // 记录订单状态变更历史 - await orderHistoryService.Add(new OrderHistory() + // 保存往来单据 + if (input.feedback != null && input.feedback.Count > 0) { - Pid = order.Id, - Status = item.status, - StatusTime = DateTime.Now, - CreateBy = "系统", - Remark = "(状态接收)" - }); + var outerFileIdList = input.feedback.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.feedback) + { + // 如果文件不是外部推送的,不处理 + 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()) @@ -138,8 +194,8 @@ namespace EntrustSettle.Api.Controllers MessageType = 1, MessageDesc = "状态更新推送", Remark = "", - Status = item.status, - StatusDesc = item.status switch + Status = input.status, + StatusDesc = input.status switch { 0 => "已下单", 1 => "已接单", @@ -159,18 +215,55 @@ namespace EntrustSettle.Api.Controllers FeeAmount = x.Amount }).ToList(); } - + var annexList = await orderAnnexService.AsQueryable() + .LeftJoin((o, a) => o.AnnexId == a.Id) + .Where((o, a) => o.OrderId == order.Id && a.Type == 5) + .Select((o, a) => a) + .ToListAsync(); + 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, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); queueService.Push(msg, order.CompanyId, json); } catch (Exception ex) { - logger.LogError(ex, $"订单Id[{item.id}],提单号[{order.Mblno}]接收到状态然后推送时发生未知异常:{msg}"); + logger.LogError(ex, $"订单Id[{input.id}],提单号[{order.Mblno}]接收到状态然后推送时发生未知异常:{msg}"); } }); } - return SuccessMsg($"订单Id[{item.id}],提单号[{order.Mblno}]状态更新成功"); + 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); + } } } } diff --git a/EntrustSettle.Api/Controllers/OrderController.cs b/EntrustSettle.Api/Controllers/OrderController.cs index 8e6bb6b..d03219f 100644 --- a/EntrustSettle.Api/Controllers/OrderController.cs +++ b/EntrustSettle.Api/Controllers/OrderController.cs @@ -230,7 +230,7 @@ namespace EntrustSettle.Api.Controllers // 构建提交数据 string fileNameStr = string.Join(",", annexList.Select(x => x.Name)); - string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/get?key={x.Key}")); + string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/Download?key={x.Key}")); string remark = "备注:客户所选服务:"; var projects = orderItem.ProjectType.Split(","); @@ -492,6 +492,21 @@ namespace EntrustSettle.Api.Controllers FeeAmount = x.Amount }).ToList(); } + var annexList = await orderAnnexService.AsQueryable() + .LeftJoin((o, a) => o.AnnexId == a.Id) + .Where((o, a) => o.OrderId == order.Id && a.Type == 5) + .Select((o, a) => a) + .ToListAsync(); + 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(); + } //if (changeStatusDto.FeeList != null && changeStatusDto.FeeList.Count > 0) //{ // pushDto.FeeList = changeStatusDto.FeeList.Select(x => new StatusPushDto.FeeDto() @@ -502,7 +517,10 @@ namespace EntrustSettle.Api.Controllers // }).ToList(); //} - var json = JsonConvert.SerializeObject(pushDto, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); + var json = JsonConvert.SerializeObject(pushDto, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }); queueService.Push(msg, order.CompanyId, json); } catch (Exception ex) @@ -549,7 +567,7 @@ namespace EntrustSettle.Api.Controllers var annexList = await annexService.Query(x => bindDto.AnnexIdList.Contains(x.Id)); foreach (Annex item in annexList) { - string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/get?key={x.Key}")); + string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/Download?key={x.Key}")); hydFeedbackDtoList.Add(new HydFeedbackDto() { @@ -655,7 +673,10 @@ namespace EntrustSettle.Api.Controllers pushDto.MailBillNo = bindDto.MailBillNo; } - var json = JsonConvert.SerializeObject(pushDto, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); + var json = JsonConvert.SerializeObject(pushDto, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }); queueService.Push(msg, order.CompanyId, json); } catch (Exception ex) @@ -685,7 +706,7 @@ namespace EntrustSettle.Api.Controllers } var annexList = await orderAnnexService.Db.Queryable((o, a) => o.AnnexId == a.Id) .Where((o, a) => o.OrderId == id) - .Where((o, a) => a.Type == (int)FileTypeEnum.原始附件 || a.Type == (int)FileTypeEnum.反馈附件) + .Where((o, a) => a.Type == (int)FileTypeEnum.原始附件 || a.Type == (int)FileTypeEnum.反馈附件 || a.Type == (int)FileTypeEnum.外部往来单据) .Select((o, a) => new AnnexDto() { Id = a.Id, diff --git a/EntrustSettle.Api/Program.cs b/EntrustSettle.Api/Program.cs index 177f7fc..3c453ba 100644 --- a/EntrustSettle.Api/Program.cs +++ b/EntrustSettle.Api/Program.cs @@ -137,6 +137,18 @@ internal class Program //options.SerializerSettings.Converters.Add(new NumberConverter(NumberConverterShip.Int64)); }); + JsonSerializerSettings setting = new JsonSerializerSettings(); + JsonConvert.DefaultSettings = new Func(() => + { + //日期类型默认格式化处理 + setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat; + setting.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + + //空值处理 + //setting.NullValueHandling = NullValueHandling.Ignore; + return setting; + }); + //builder.Services.AddRabbitMQSetup(); 未采用注入的方式,而是直接在需要的地方new builder.Services.AddKafkaSetup(builder.Configuration); builder.Services.AddEventBusSetup(); diff --git a/EntrustSettle.Model/CustomEnums/BusinessEnums.cs b/EntrustSettle.Model/CustomEnums/BusinessEnums.cs index a126c4c..fe37e72 100644 --- a/EntrustSettle.Model/CustomEnums/BusinessEnums.cs +++ b/EntrustSettle.Model/CustomEnums/BusinessEnums.cs @@ -30,6 +30,7 @@ namespace EntrustSettle.Model 原始附件 = 1, 反馈附件 = 2, 账单 = 3, - 发票 = 4 + 发票 = 4, + 外部往来单据 = 5 } } \ No newline at end of file diff --git a/EntrustSettle.Model/Dtos/Hyd/HydQueryResultDto.cs b/EntrustSettle.Model/Dtos/Hyd/HydQueryResultDto.cs index 7a29591..61904c3 100644 --- a/EntrustSettle.Model/Dtos/Hyd/HydQueryResultDto.cs +++ b/EntrustSettle.Model/Dtos/Hyd/HydQueryResultDto.cs @@ -1,11 +1,40 @@ -namespace EntrustSettle.Model.Dtos +using System; +using System.Collections.Generic; + +namespace EntrustSettle.Model.Dtos { public class HydQueryResultDto { public long id { get; set; } public string billNo { get; set; } public int status { get; set; } - //public string fileName { get; set; } - //public string fileUrl { get; set; } + public List feedback { get; set; } + public class Feedback + { + /// + /// 1=海运达推送的文件 + /// + public int sendType { get; set; } + /// + /// 文件id + /// + public long id { get; set; } + /// + /// 反馈信息上传附件地址 + /// + public string fileUrl { get; set; } + /// + /// 反馈信息上传附件文件名 + /// + public string fileName { get; set; } + /// + /// 反馈信息备注 + /// + public string remark { get; set; } + /// + /// 反馈信息添加时间 + /// + public DateTime? createTime { get; set; } + } } } diff --git a/EntrustSettle.Model/Dtos/Queue/StatusPushDto.cs b/EntrustSettle.Model/Dtos/Queue/StatusPushDto.cs index 1b6b3bb..ddec910 100644 --- a/EntrustSettle.Model/Dtos/Queue/StatusPushDto.cs +++ b/EntrustSettle.Model/Dtos/Queue/StatusPushDto.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace EntrustSettle.Model.Dtos { @@ -46,5 +47,33 @@ namespace EntrustSettle.Model.Dtos /// public decimal FeeAmount { get; set; } } + + /// + /// 海运达往来单据列表 + /// + public List FeebackAnnexList { get; set; } + + /// + /// 海运达往来单据 + /// + public class FeebackAnnex + { + /// + /// 附件Id + /// + public long Id { get; set; } + /// + /// 附件名称 + /// + public string FileName { get; set; } + /// + /// 附件备注 + /// + public string Remark { get; set; } + /// + /// 附件添加时间 + /// + public DateTime? BusinessTime { get; set; } + } } } diff --git a/EntrustSettle.Model/Models/Annex.cs b/EntrustSettle.Model/Models/Annex.cs index 9183e71..e3adb26 100644 --- a/EntrustSettle.Model/Models/Annex.cs +++ b/EntrustSettle.Model/Models/Annex.cs @@ -1,4 +1,5 @@ using SqlSugar; +using System; namespace EntrustSettle.Model.Models { @@ -17,10 +18,22 @@ namespace EntrustSettle.Model.Models /// public string Path { get; set; } /// - /// 附件类型 1:原始附件 2:反馈附件 3:账单 4:发票 + /// 附件类型 1:原始附件 2:反馈附件 3:账单 4:发票 5:外部往来单据 /// public int Type { get; set; } /// + /// 外部系统的备注(文件类型为外部往来单据时会使用此字段) + /// + public string Remark { get; set; } + /// + /// 外部系统的业务发生时间(文件类型为外部往来单据时会使用此字段) + /// + public DateTime? BusinessTime { get; set; } + /// + /// 外部系统的文件Id(文件类型为外部往来单据时会使用此字段) + /// + public long? OuterFileId { get; set; } + /// /// 用于外部文件下载时确认文件及验证 /// public string Key { get; set; } diff --git a/EntrustSettle.Services/QueueService.cs b/EntrustSettle.Services/QueueService.cs index dbe2752..0b140f2 100644 --- a/EntrustSettle.Services/QueueService.cs +++ b/EntrustSettle.Services/QueueService.cs @@ -44,7 +44,7 @@ namespace EntrustSettle.Services conn.Close(); - logger.LogInformation($"{opType},已发送数据到消息队列,数据内容:【{data}】"); + logger.LogInformation($"{opType},已发送数据到消息队列,队列名称:【{queueName}】,数据内容:【{data}】"); } } catch (Exception) diff --git a/EntrustSettle.Tasks/QuartzNet/Jobs/JobHydSubmitQuartz.cs b/EntrustSettle.Tasks/QuartzNet/Jobs/JobHydSubmitQuartz.cs index cdcc3da..e3a96fd 100644 --- a/EntrustSettle.Tasks/QuartzNet/Jobs/JobHydSubmitQuartz.cs +++ b/EntrustSettle.Tasks/QuartzNet/Jobs/JobHydSubmitQuartz.cs @@ -76,7 +76,7 @@ namespace EntrustSettle.Tasks // 构建提交数据 string fileNameStr = string.Join(",", annexList.Select(x => x.Name)); - string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/get?key={x.Key}")); + string fileUrl = string.Join(",", annexList.Select(x => $"{domainUrl}/api/Annex/Download?key={x.Key}")); string remark = "备注:客户所选服务:"; var projects = orderItem.ProjectType.Split(",");