推送接收

master
zhangxiaofeng 5 months ago
parent 1e7cd8e470
commit f16df65f04

@ -1,7 +1,7 @@
using EntrustSettle.Common;
using EntrustSettle.Common.Caches;
using EntrustSettle.Controllers;
using EntrustSettle.IServices;
using EntrustSettle.IServices.Base;
using EntrustSettle.Model;
using EntrustSettle.Model.Dtos;
using EntrustSettle.Model.Models;
@ -25,13 +25,16 @@ namespace EntrustSettle.Api.Controllers
private readonly IOrderHistoryService orderHistoryService;
private readonly IQueueService queueService;
private readonly IOrderFeeService orderFeeService;
private readonly IBaseServices<InvoiceApply> invoiceApplyService;
public OpenController(IOrderService orderService,
ILogger<OpenController> logger,
IOrderHistoryService orderHistoryService,
IQueueService queueService,
IOrderFeeService orderFeeService,
IAnnexService annexService,
IOrderAnnexService orderAnnexService)
IOrderAnnexService orderAnnexService,
IBaseServices<InvoiceApply> invoiceApplyService)
{
this.orderService = orderService;
this.logger = logger;
@ -40,6 +43,7 @@ namespace EntrustSettle.Api.Controllers
this.orderFeeService = orderFeeService;
this.annexService = annexService;
this.orderAnnexService = orderAnnexService;
this.invoiceApplyService = invoiceApplyService;
}
/// <summary>
@ -90,6 +94,26 @@ namespace EntrustSettle.Api.Controllers
return result;
}
/// <summary>
/// 发票申请
/// </summary>
[HttpPost]
[ApiUser(ApiCode = "EntrustSettle")]
public async Task<MessageModel> ApplyInvoice(ApplyInvoiceDto input)
{
var result = await App.GetService<OrderController>().ApplyInvoice(input);
return result;
}
/// <summary>
/// 账单申请
/// </summary>
[HttpPost]
[ApiUser(ApiCode = "EntrustSettle")]
public async Task<MessageModel> ApplyBill(ApplyBillDto input)
{
var result = await App.GetService<OrderController>().ApplyBill(input);
return result;
}
/// <summary>
/// 海运达状态回推接口
/// </summary>
@ -97,99 +121,144 @@ namespace EntrustSettle.Api.Controllers
[ApiUser(ApiCode = "PushOrderStatus")]
public async Task<MessageModel> PushOrderStatus([FromBody] HydQueryResultDto input)
{
// 推送类型 1:订单状态、费用、账单、外部往来单据 2:发票
int pushType = 0;
List<InvoiceApply> invoiceApplyList = null;
var orderList = await orderService.Query(x => x.Bsno == input.id);
if (orderList == null || orderList.Count == 0)
if (orderList != null && orderList.Count > 0)
{
string msg = $"订单Id[{input.id}]接收到回推后未查询到本地订单";
logger.LogInformation(msg);
return FailedMsg(msg);
pushType = 1;
logger.LogInformation($"订单Id[{input.id}]接收到回推后,判断操作类型为[反馈订单状态/费用/外部往来单据/账单]");
}
if (orderList.Count > 1)
else
{
string msg = $"订单Id[{input.id}]接收到回推后根据Id查询到多个本地订单{string.Join(',', orderList.Select(x => x.Mblno))}";
logger.LogInformation(msg);
return FailedMsg(msg);
invoiceApplyList = await invoiceApplyService.Query(x => x.Bsno == input.id);
if (invoiceApplyList != null && invoiceApplyList.Count > 0)
{
pushType = 2;
logger.LogInformation($"订单Id[{input.id}]接收到回推后,判断操作类型为[反馈发票]");
}
else
{
string msg = $"订单Id[{input.id}]接收到回推后未查询到本地订单或发票申请订单";
logger.LogInformation(msg);
return FailedMsg(msg);
}
}
var order = orderList[0];
// 保存往来单据
if (input.feedbackList != null && input.feedbackList.Count > 0)
if (pushType == 1)
{
var outerFileIdList = input.feedbackList.Select(x => x.id).ToList();
var existsOuterFileIdList = await orderAnnexService.AsQueryable()
.LeftJoin<Annex>((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;
var order = orderList[0];
// 如果文件信息已经存在,不处理
if (existsOuterFileIdList.Contains(item.id))
continue;
bool isHasBill = false;
// 保存附件信息
var annex = new Annex()
{
Type = 5,
OuterFileId = item.id,
Name = item.fileName,
Remark = item.remark,
BusinessTime = item.createTime,
//Path = relativePath
};
string fullPath = null;
if (!string.IsNullOrEmpty(item.fileUrl))
// 保存【往来单据附件】或【账单附件】
if (input.feedbackList != null && input.feedbackList.Count > 0)
{
var outerFileIdList = input.feedbackList.Select(x => x.id).ToList();
var existsOuterFileIdList = await orderAnnexService.AsQueryable()
.LeftJoin<Annex>((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)
{
// 检查文件保存目录
var dir = Path.Combine(App.WebHostEnvironment.WebRootPath, "files");
if (!Directory.Exists(dir))
// 如果文件不是外部推送的,不处理
if (item.sendType != 1)
continue;
// 如果文件信息已经存在,不处理
if (existsOuterFileIdList.Contains(item.id))
continue;
// 保存附件信息
var annex = new Annex()
{
OuterFileId = item.id,
Name = item.fileName,
Remark = item.remark,
BusinessTime = item.createTime,
//Path = relativePath
//Type
};
// 海运达规定:海运达返回的账单会以“[反馈账单]”为开头同时billApplyFlag = 1
if (item.billApplyFlag == 1 && item.remark?.StartsWith("[反馈账单]") == true)
{
Directory.CreateDirectory(dir);
annex.Type = 3;
isHasBill = true;
}
else
{
annex.Type = 5;
}
// 文件名
var newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(item.fileName);
string fullPath = null;
if (!string.IsNullOrEmpty(item.fileUrl))
{
// 检查文件保存目录
var dir = Path.Combine(App.WebHostEnvironment.WebRootPath, "files");
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
// 相对路径
var relativePath = Path.Combine("files", newFileName);
// 文件名
var newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(item.fileName);
// 完整路径
fullPath = Path.Combine(dir, newFileName);
// 相对路径
var relativePath = Path.Combine("files", newFileName);
annex.Path = relativePath;
}
await annexService.Add(annex);
// 完整路径
fullPath = Path.Combine(dir, newFileName);
var orderAnnex = new OrderAnnex()
{
OrderId = order.Id,
AnnexId = annex.Id
};
await orderAnnexService.Add(orderAnnex);
annex.Path = relativePath;
}
await annexService.Add(annex);
if (!string.IsNullOrEmpty(item.fileUrl))
{
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);
var orderAnnex = new OrderAnnex()
{
OrderId = order.Id,
AnnexId = annex.Id
};
await orderAnnexService.Add(orderAnnex);
if (!string.IsNullOrEmpty(item.fileUrl))
{
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(() =>
// 更新订单状态
bool isUpdate = false;
var orderUpdateable = orderService.AsUpdateable();
if (input.status != null && input.status != order.Status)
{
isUpdate = true;
order.Status = input.status;
orderUpdateable.SetColumns(x => x.Status == input.status);
}
if (isHasBill)
{
isUpdate = true;
orderUpdateable.SetColumns(x => x.IsApplyBill == false);
}
if (isUpdate)
{
await orderUpdateable.Where(x => x.Bsno == input.id).ExecuteCommandAsync();
}
// 将更新后的状态、费用、外部往来单据 推送到消息队列
// 将账单附件 推送到消息队列
if (AppSettings.app("RabbitMQ", "Enabled").ObjToBool())
{
string logTitle = $"Id[{order.Id}],提单号[{order.Mblno}],推送费用、状态、往来单据";
try
{
StatusPushDto pushDto = new()
@ -199,7 +268,7 @@ namespace EntrustSettle.Api.Controllers
MessageType = 1,
MessageDesc = "状态更新推送",
Remark = "",
Status = input.status,
Status = order.Status ?? 0,
StatusDesc = input.status switch
{
0 => "已下单",
@ -236,51 +305,219 @@ namespace EntrustSettle.Api.Controllers
}).ToList();
}
var json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
queueService.Push(msg, order.CompanyId, json);
queueService.Push(logTitle, order.CompanyId, json);
}
catch (Exception ex)
{
logger.LogError(ex, $"订单Id[{input.id}],提单号[{order.Mblno}]接收到状态然后推送时发生未知异常:{msg}");
logger.LogError(ex, $"{logTitle}时发生未知异常");
}
});
}
if (order.Status != input.status)
if (isHasBill)
{
string logTitle2 = $"订单Id[{input.id}],提单号[{order.Mblno}],接收到账单然后推送账单";
try
{
var billIdList = await orderAnnexService.AsQueryable()
.LeftJoin<Annex>((o, a) => o.AnnexId == a.Id)
.Where((o, a) => o.OrderId == order.Id && a.Type == 3)
.Select((o, a) => a.Id)
.ToListAsync();
BillPushDto pushDto = new()
{
OrderId = order.Id,
Mblno = order.Mblno,
AnnexIdList = billIdList,
MessageType = 2,
MessageDesc = "账单附件信息推送"
};
var json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
});
queueService.Push(logTitle2, order.CompanyId, json);
}
catch (Exception ex)
{
logger.LogError(ex, $"{logTitle2}时发生未知异常");
}
}
}
return SuccessMsg();
}
else if (pushType == 2)
{
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()
List<long> waitSendOrderIdList = new();
if (input.feedbackList != null && input.feedbackList.Count > 0)
{
Pid = order.Id,
Status = input.status,
StatusTime = DateTime.Now,
CreateBy = "系统",
Remark = "(状态接收)"
});
return SuccessMsg($"订单Id[{input.id}],提单号[{order.Mblno}]状态更新成功");
var outerFileIdList = input.feedbackList.Select(x => x.id).ToList();
foreach (var feedbackItem in input.feedbackList)
{
// 如果文件不是外部推送的,不处理
if (feedbackItem.sendType != 1)
continue;
// 待绑定此发票附件的订单Id列表
List<long> waitBindOrderIdList = new();
// 如果文件信息已经存在,不处理
foreach (var applyItem in invoiceApplyList)
{
var isExists = await orderAnnexService.AsQueryable()
.LeftJoin<Annex>((o, a) => o.AnnexId == a.Id)
.Where((o, a) => a.OuterFileId == feedbackItem.id && o.OrderId == applyItem.OrderId)
.AnyAsync();
if (!isExists)
{
waitBindOrderIdList.Add(applyItem.OrderId);
}
}
if (waitBindOrderIdList.Count == 0)
{
continue;
}
waitSendOrderIdList.AddRange(waitBindOrderIdList);
// 保存附件信息
var annex = new Annex()
{
OuterFileId = feedbackItem.id,
Name = feedbackItem.fileName,
Remark = feedbackItem.remark,
BusinessTime = feedbackItem.createTime,
Type = 4,
//Path = relativePath
};
string fullPath = null;
if (!string.IsNullOrEmpty(feedbackItem.fileUrl))
{
// 检查文件保存目录
var dir = Path.Combine(App.WebHostEnvironment.WebRootPath, "files");
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
// 文件名
var newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(feedbackItem.fileName);
// 相对路径
var relativePath = Path.Combine("files", newFileName);
// 完整路径
fullPath = Path.Combine(dir, newFileName);
annex.Path = relativePath;
}
await annexService.Add(annex);
// 下载附件
if (!string.IsNullOrEmpty(feedbackItem.fileUrl))
{
var restClient = new RestClient(feedbackItem.fileUrl);
var request = new RestRequest();
using var stream = await restClient.DownloadStreamAsync(request);
using FileStream fileStream = new FileStream(fullPath, FileMode.Create);
await stream.CopyToAsync(fileStream);
}
// 为订单列表统一绑定此附件
var orderAnndexList = waitBindOrderIdList.Select(x => new OrderAnnex()
{
OrderId = x,
AnnexId = annex.Id
}).ToList();
await orderAnnexService.Add(orderAnndexList);
}
}
if (waitSendOrderIdList.Count != 0)
{
waitSendOrderIdList = waitSendOrderIdList.Distinct().ToList();
// 更新订单状态
await orderService.AsUpdateable()
.SetColumns(x => x.IsApplyInvoice == false)
.Where(x => waitSendOrderIdList.Contains(x.Id))
.ExecuteCommandAsync();
// 将 发票附件 推送到消息队列
var orderInfoList = await orderService.AsQueryable().Where(x => waitSendOrderIdList.Contains(x.Id))
.Select(x => new
{
x.Id,
x.Mblno,
x.CompanyId,
x.MailBillNo,
x.MailFlag,
}).ToListAsync();
var logTitle = $"Id列表[{string.Join(',', orderInfoList.Select(x => x.Id))}],提单号列表:[{string.Join(',', orderInfoList.Select(x => x.Mblno))}],将每一票所有的发票推送队列";
logger.LogInformation(logTitle);
try
{
var invoiceAnnexList = await orderAnnexService.AsQueryable()
.LeftJoin<Annex>((o, a) => o.AnnexId == a.Id)
.Where((o, a) => waitSendOrderIdList.Contains(o.OrderId) && a.Type == 4)
.Select((o, a) => o)
.ToListAsync();
foreach (var item in orderInfoList)
{
var invoiceAnnexIdList = invoiceAnnexList.Where(x => x.OrderId == item.Id).Select(x => x.AnnexId).ToList();
if (invoiceAnnexIdList.Count == 0) continue;
var logItemTitle = $"Id[{item.Id}],提单号:[{item.Mblno}]附件Id列表[({string.Join(',', invoiceAnnexIdList)})]开始推送队列";
BillPushDto pushDto = new()
{
MessageType = 3,
MessageDesc = "发票附件信息推送",
AnnexIdList = invoiceAnnexIdList,
OrderId = item.Id,
Mblno = item.Mblno,
MailFlag = item.MailFlag,
MailBillNo = item.MailBillNo,
};
var json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
});
queueService.Push(logItemTitle, orderInfoList.FirstOrDefault().CompanyId, json);
}
}
catch (Exception ex)
{
logger.LogError(ex, $"{logTitle}的过程中发生未知异常");
}
}
return SuccessMsg();
}
else
{
string msg = $"订单Id[{input.id}],提单号[{order.Mblno}]状态不变";
logger.LogInformation(msg);
return SuccessMsg(msg);
throw new Exception($"订单Id[{input.id}]接收到回推后,无法判断操作类型");
}
}
[HttpGet]
public string TestTime()
{
return DateTime.Now.ToString();
}
[HttpGet]
public void TestError()
{
throw new Exception("测试异常");
}
//[HttpGet]
//public string TestTime()
//{
// return DateTime.Now.ToString();
//}
//[HttpGet]
//public void TestError()
//{
// throw new Exception("测试异常");
//}
//[HttpGet]
//public async Task<MessageModel> TestSetRedis(string key, string value)

@ -740,6 +740,61 @@ namespace EntrustSettle.Api.Controllers
logger.LogError(ex, $"{msg},失败");
}
});
//_ = Task.Run(() =>
//{
// string msg = $"Id[{order.Id}],提单号:[{order.Mblno}]";
// try
// {
// string json = null;
// if (bindDto.OperType is FileTypeEnum.账单)
// {
// msg += "更新账单后推送队列";
// BillPushDto pushDto = new()
// {
// MessageType = 2,
// MessageDesc = "账单附件信息推送",
// AnnexIdList = bindDto.AnnexIdList,
// OrderId = order.Id,
// Mblno = order.Mblno,
// };
// json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings()
// {
// NullValueHandling = NullValueHandling.Ignore
// });
// }
// else if (bindDto.OperType == FileTypeEnum.发票)
// {
// msg += "更新发票后推送队列";
// InvoicePushDto pushDto = new()
// {
// MessageType = 3,
// MessageDesc = "发票附件信息推送",
// AnnexIdList = bindDto.AnnexIdList,
// OrderList = new List<InvoicePushDto.OrderInfo>()
// {
// new InvoicePushDto.OrderInfo()
// {
// OrderId = order.Id,
// Mblno = order.Mblno,
// MailFlag = bindDto.MailFlag,
// MailBillNo = bindDto.MailBillNo,
// }
// }
// };
// json = JsonConvert.SerializeObject(pushDto, Formatting.Indented, new JsonSerializerSettings()
// {
// NullValueHandling = NullValueHandling.Ignore
// });
// }
// queueService.Push(msg, order.CompanyId, json);
// }
// catch (Exception ex)
// {
// logger.LogError(ex, $"{msg},失败");
// }
//});
}
return SuccessMsg();
@ -844,7 +899,7 @@ namespace EntrustSettle.Api.Controllers
{
Pid = x.Id,
StatusTime = DateTime.Now,
Status = 6,
Status = 5,
Remark = input.Remark,
}).ToList();
await orderHistoryService.Add(orderStatusModelList);
@ -892,7 +947,7 @@ namespace EntrustSettle.Api.Controllers
{
Pid = order.Id,
StatusTime = DateTime.Now,
Status = 7,
Status = 6,
Remark = input.Remark,
});

@ -2,6 +2,6 @@
{
public interface IQueueService
{
void Push(string opType, string companyId, string data);
void Push(string logTitle, string companyId, string data);
}
}

@ -7,10 +7,16 @@ namespace EntrustSettle.Model.Dtos
{
public long id { get; set; }
public string billNo { get; set; }
public int status { get; set; }
public int? status { get; set; }
//public string remark { get; set; }
public List<Feedback> feedbackList { get; set; }
public class Feedback
{
/// <summary>
/// 1-申请账单
/// </summary>
public int billApplyFlag { get; set; }
/// <summary>
/// 1=海运达推送的文件
/// </summary>

@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace EntrustSettle.Model.Dtos
namespace EntrustSettle.Model.Dtos
{
/// <summary>
/// 账单申请Dto类

@ -16,14 +16,5 @@ namespace EntrustSettle.Model.Dtos
/// 消息类型说明
/// </summary>
public string MessageDesc { get; set; }
/// <summary>
/// 订单Id
/// </summary>
public long OrderId { get; set; }
/// <summary>
/// 提单号
/// </summary>
public string Mblno { get; set; }
}
}

@ -3,22 +3,34 @@
namespace EntrustSettle.Model.Dtos
{
/// <summary>
/// 委托结算消息队列推送Dto - 发票账单
/// 委托结算消息队列推送Dto - 账单和发票
/// </summary>
public class BillPushDto : BasePushDto
{
/// <summary>
/// 账单或发票附件的Id列表用于获取账单或发票
/// 订单Id
/// </summary>
public List<long> AnnexIdList { get; set; }
public long OrderId { get; set; }
/// <summary>
/// 提单号
/// </summary>
public string Mblno { get; set; }
/// <summary>
/// 是否邮寄(如果推送类型为发票推送)
/// 是否邮寄
/// </summary>
public bool? MailFlag { get; set; }
/// <summary>
/// 快递单号(如果推送类型为发票推送
/// 快递单号
/// </summary>
public string MailBillNo { get; set; }
/// <summary>
/// 账单附件的Id列表用于获取账单
/// </summary>
public List<long> AnnexIdList { get; set; }
}
}

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
namespace EntrustSettle.Model.Dtos
{
///// <summary>
///// 委托结算消息队列推送Dto - 发票
///// </summary>
//[Obsolete("This class is deprecated, use BillPushDto instead.")]
//public class InvoicePushDto : BasePushDto
//{
// /// <summary>
// /// 发票附件的Id列表用于获取发票
// /// </summary>
// public List<long> AnnexIdList { get; set; }
// public long OrderId { get; set; }
// public string Mblno { get; set; }
// /// <summary>
// /// 是否邮寄
// /// </summary>
// public bool? MailFlag { get; set; }
// /// <summary>
// /// 快递单号
// /// </summary>
// public string MailBillNo { get; set; }
// //public List<OrderInfo> OrderList { get; set; }
// //public class OrderInfo
// //{
// //}
//}
}

@ -8,6 +8,15 @@ namespace EntrustSettle.Model.Dtos
/// </summary>
public class StatusPushDto : BasePushDto
{
/// <summary>
/// 订单Id
/// </summary>
public long OrderId { get; set; }
/// <summary>
/// 提单号
/// </summary>
public string Mblno { get; set; }
/// <summary>
/// 状态编码 已下单=0 已接单=1 待缴费=2 已缴费=3 已完结=4
/// </summary>

@ -22,15 +22,15 @@ namespace EntrustSettle.Model.Models
/// </summary>
public int Type { get; set; }
/// <summary>
/// 外部系统的备注(文件类型为外部往来单据时会使用此字段)
/// 外部系统的备注(文件类型为外部往来单据、或者发票、或者账单时会使用此字段)
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 外部系统的业务发生时间(文件类型为外部往来单据时会使用此字段)
/// 外部系统的业务发生时间(文件类型为外部往来单据、或者发票、或者账单时会使用此字段)
/// </summary>
public DateTime? BusinessTime { get; set; }
/// <summary>
/// 外部系统的文件Id文件类型为外部往来单据时会使用此字段)
/// 外部系统的文件Id文件类型为外部往来单据、或者发票、或者账单时会使用此字段)
/// </summary>
public long? OuterFileId { get; set; }
/// <summary>

@ -15,7 +15,7 @@ namespace EntrustSettle.Services
{
this.logger = logger;
}
public void Push(string opType, string compId, string data)
public void Push(string logTitle, string compId, string data)
{
var mqUrl = AppSettings.app("RabbitMQ", "ConnectionString");
try
@ -44,7 +44,7 @@ namespace EntrustSettle.Services
conn.Close();
logger.LogInformation($"{opType},已发送数据到消息队列,队列名称:【{queueName}】,数据内容:{Environment.NewLine}{data}");
logger.LogInformation($"{logTitle},已发送数据到消息队列,队列名称:【{queueName}】,数据内容:{Environment.NewLine}{data}");
}
}
catch (Exception)

Loading…
Cancel
Save