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);
}
}
}
}