|
|
|
|
using Furion;
|
|
|
|
|
using Furion.DataEncryption;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using Furion.UnifyResult;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Myshipping.Application.Entity;
|
|
|
|
|
using Myshipping.Application.Service.ExpressDelivery.Dto;
|
|
|
|
|
using Myshipping.Application.Service.ExpressDelivery.Dto.SF;
|
|
|
|
|
using Myshipping.Core;
|
|
|
|
|
using Myshipping.Core.Attributes;
|
|
|
|
|
using Myshipping.Core.Service;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 快递订单服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
[ApiDescriptionSettings("Application", Name = "ExpressDelivery", Description = "快递订单服务", Order = 20)]
|
|
|
|
|
[Route("/ExpressDelivery")]
|
|
|
|
|
public class ExpressDeliveryService : IExpressDeliveryService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private const string STATUS_ASSOCIATION = "关联快递订单";
|
|
|
|
|
private const string STATUS_DISASSOCIATION = "取消关联快递订单";
|
|
|
|
|
private const string STATUS_DELETE = "关联快递订单已删除";
|
|
|
|
|
private const string STATUS_SEND = "快递已下单";
|
|
|
|
|
private const string STATUS_CANCEL = "快递已消单";
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 保存面单文件的文件夹名称
|
|
|
|
|
/// </summary>
|
|
|
|
|
private const string WAY_BILL_DIRECTORY = "WaybillFile";
|
|
|
|
|
|
|
|
|
|
private readonly ILogger<ExpressDeliveryService> _logger;
|
|
|
|
|
private readonly ISysCacheService _cache;
|
|
|
|
|
private readonly SqlSugarRepository<BookingStatusLog> _bookingStatuslogRep;
|
|
|
|
|
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRep;
|
|
|
|
|
private readonly SqlSugarRepository<ExpressDeliveryOrder> _orderRep;
|
|
|
|
|
private readonly SqlSugarRepository<ExpressDeliveryBusiness> _businessRep;
|
|
|
|
|
private readonly SqlSugarRepository<ExpressDeliveryStatus> _statusRep;
|
|
|
|
|
private readonly SqlSugarRepository<ExpressDeliveryAddress> _addressRep;
|
|
|
|
|
private readonly SqlSugarRepository<ExpressDeliveryFee> _feeRep;
|
|
|
|
|
private readonly INamedServiceProvider<IDeliverySend> _deliverySendServiceProvider;
|
|
|
|
|
|
|
|
|
|
public ExpressDeliveryService(ILogger<ExpressDeliveryService> logger,
|
|
|
|
|
ISysCacheService cache,
|
|
|
|
|
SqlSugarRepository<BookingStatusLog> bookingStatuslogRep,
|
|
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRep,
|
|
|
|
|
SqlSugarRepository<ExpressDeliveryOrder> orderRep,
|
|
|
|
|
SqlSugarRepository<ExpressDeliveryBusiness> businessRep,
|
|
|
|
|
SqlSugarRepository<ExpressDeliveryStatus> statusRep,
|
|
|
|
|
SqlSugarRepository<ExpressDeliveryAddress> templeteRep,
|
|
|
|
|
INamedServiceProvider<IDeliverySend> deliverySendServiceProvider,
|
|
|
|
|
SqlSugarRepository<ExpressDeliveryFee> feeRep)
|
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_cache = cache;
|
|
|
|
|
_orderRep = orderRep;
|
|
|
|
|
_businessRep = businessRep;
|
|
|
|
|
_statusRep = statusRep;
|
|
|
|
|
_bookingStatuslogRep = bookingStatuslogRep;
|
|
|
|
|
_bookingOrderRep = bookingOrderRep;
|
|
|
|
|
_addressRep = templeteRep;
|
|
|
|
|
_deliverySendServiceProvider = deliverySendServiceProvider;
|
|
|
|
|
_feeRep = feeRep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 分页查询快递主表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("Page")]
|
|
|
|
|
public async Task<SqlSugarPagedList<ExpressDeliveryDto>> Page([FromQuery] ExpressDeliveryInput input)
|
|
|
|
|
{
|
|
|
|
|
var entities = await _orderRep.AsQueryable().Filter(null, true)
|
|
|
|
|
.Where(x => x.TenantId == UserManager.TENANT_ID && x.IsDeleted == false)
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.KDNO), u => u.KDNO.Contains(input.KDNO))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.SJCompany), u => u.SJCompany.Contains(input.SJCompany))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.SJPeople), u => u.SJPeople.Contains(input.SJPeople))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.SJTel), u => u.SJTel.Contains(input.SJTel))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.FJCompany), u => u.FJCompany.Contains(input.FJCompany))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.FJPeople), u => u.FJPeople.Contains(input.FJPeople))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.FJTel), u => u.FJTel.Contains(input.FJTel))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.VESSEL), u => u.VESSEL.Contains(input.VESSEL))
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.VOYNO), u => u.VOYNO.Contains(input.VOYNO))
|
|
|
|
|
.WhereIF(input.BDate != null, u => u.Date >= input.BDate)
|
|
|
|
|
.WhereIF(input.EDate != null, u => u.Date <= input.EDate)
|
|
|
|
|
.OrderBy(PageInputOrder.OrderBuilder(input.SortField, input.DescSort))
|
|
|
|
|
.ToPagedListAsync(input.PageNo, input.PageSize);
|
|
|
|
|
|
|
|
|
|
var list = entities.Adapt<SqlSugarPagedList<ExpressDeliveryDto>>();
|
|
|
|
|
foreach (var item in list.Items)
|
|
|
|
|
{
|
|
|
|
|
item.Business = await _businessRep.AsQueryable().Filter(null, true).Where(x => x.PId == item.Id).ToListAsync();
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("Get")]
|
|
|
|
|
public async Task<ExpressDeliveryDto> Get(long Id)
|
|
|
|
|
{
|
|
|
|
|
ExpressDeliveryDto ordOut = new ExpressDeliveryDto();
|
|
|
|
|
var main = await _orderRep.FirstOrDefaultAsync(u => u.Id == Id);
|
|
|
|
|
if (main != null)
|
|
|
|
|
{
|
|
|
|
|
ordOut = main.Adapt<ExpressDeliveryDto>();
|
|
|
|
|
var business = await _businessRep.AsQueryable().Where(x => x.PId == Id).ToListAsync();
|
|
|
|
|
ordOut.Business = business;
|
|
|
|
|
|
|
|
|
|
var feeList = await _feeRep.AsQueryable().Where(x => x.OrderId == Id).ToListAsync();
|
|
|
|
|
ordOut.FeeList = feeList;
|
|
|
|
|
}
|
|
|
|
|
return ordOut;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 保存并返回数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("Save")]
|
|
|
|
|
[JoinValidateMessge]
|
|
|
|
|
public async Task<ExpressDeliveryDto> Save(ExpressDeliveryDto input)
|
|
|
|
|
{
|
|
|
|
|
var entity = input.Adapt<ExpressDeliveryOrder>();
|
|
|
|
|
|
|
|
|
|
string logGuid = Guid.NewGuid().ToString();
|
|
|
|
|
_logger.LogInformation($"快递订单保存操作开始,{logGuid}");
|
|
|
|
|
|
|
|
|
|
if (input.Id == 0)
|
|
|
|
|
{
|
|
|
|
|
entity.CurrentStateCode = "DJY02";
|
|
|
|
|
entity.CurrentStateDesc = "已保存";
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"快递订单新增操作开始,{logGuid}");
|
|
|
|
|
|
|
|
|
|
await _orderRep.InsertAsync(entity);
|
|
|
|
|
if (input.Business != null && input.Business.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
#region 保存关联的业务信息
|
|
|
|
|
_logger.LogInformation($"快递订单新增关联的业务信息,{logGuid}");
|
|
|
|
|
input.Business.ForEach(b => b.PId = entity.Id);
|
|
|
|
|
await _businessRep.InsertAsync(input.Business);
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 向与快递关联的订舱列表中添加动态
|
|
|
|
|
List<string> mblNoList = input.Business.Select(b => b.MBLNO).ToList();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(mblNoList, STATUS_ASSOCIATION);
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加快递动态
|
|
|
|
|
_logger.LogInformation($"快递订单新增快递动态,{logGuid}");
|
|
|
|
|
var status = new ExpressDeliveryStatus()
|
|
|
|
|
{
|
|
|
|
|
OrderId = entity.Id,
|
|
|
|
|
MailNo = "",
|
|
|
|
|
StatusCode = entity.CurrentStateCode,
|
|
|
|
|
StatusDesc = entity.CurrentStateDesc
|
|
|
|
|
};
|
|
|
|
|
await _statusRep.InsertAsync(status);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var oldOrder = _orderRep.FirstOrDefault(x => x.Id == input.Id);
|
|
|
|
|
if (oldOrder.CurrentStateCode != "DJY02")
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("修改失败,原因:下单过的快递单无法修改信息");
|
|
|
|
|
}
|
|
|
|
|
_logger.LogInformation($"快递订单修改操作开始,{logGuid}");
|
|
|
|
|
await _orderRep.AsUpdateable(entity).IgnoreColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.CurrentStateCode,
|
|
|
|
|
it.CurrentStateDesc,
|
|
|
|
|
it.TenantId,
|
|
|
|
|
it.CreatedTime,
|
|
|
|
|
it.CreatedUserId,
|
|
|
|
|
it.CreatedUserName,
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
#region 向与快递关联的订舱列表中添加动态,并新增或更新业务信息
|
|
|
|
|
List<ExpressDeliveryBusiness> businessList = await _businessRep.AsQueryable().Where(x => x.PId == input.Id).ToListAsync();
|
|
|
|
|
if (businessList.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
if (input.Business?.Count != 0)
|
|
|
|
|
{
|
|
|
|
|
// 直接得到:要关联快递的提单号列表
|
|
|
|
|
List<string> mblNoList = input.Business.Select(b => b.MBLNO).ToList();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(mblNoList, STATUS_ASSOCIATION);
|
|
|
|
|
|
|
|
|
|
// 直接得到:要新增的业务信息
|
|
|
|
|
input.Business.ForEach(b => b.PId = entity.Id);
|
|
|
|
|
await _businessRep.InsertAsync(input.Business);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (input.Business?.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
// 直接得到:要取消关联快递的提单号列表
|
|
|
|
|
List<string> mblNoList = businessList.Select(b => b.MBLNO).ToList();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(mblNoList, STATUS_DISASSOCIATION);
|
|
|
|
|
|
|
|
|
|
// 直接得到:要删除的业务信息
|
|
|
|
|
await _businessRep.DeleteAsync(x => x.PId == entity.Id);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// 分析对比,判断哪些关联,哪些取消关联
|
|
|
|
|
List<string> oldMblnoList = businessList.Select(b => b.MBLNO).ToList();
|
|
|
|
|
List<string> newMblnoList = input.Business.Select(b => b.MBLNO).ToList();
|
|
|
|
|
|
|
|
|
|
// 新增关联的提单号列表:
|
|
|
|
|
List<string> addMblnoList = newMblnoList.Except(oldMblnoList).ToList();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(addMblnoList, STATUS_ASSOCIATION);
|
|
|
|
|
|
|
|
|
|
// 取消关联的提单号列表
|
|
|
|
|
List<string> cancelMblnoList = oldMblnoList.Except(newMblnoList).ToList();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(cancelMblnoList, STATUS_DISASSOCIATION);
|
|
|
|
|
|
|
|
|
|
// 先删除,再新增业务信息
|
|
|
|
|
await _businessRep.DeleteAsync(x => x.PId == entity.Id);
|
|
|
|
|
input.Business.ForEach(b => b.PId = entity.Id);
|
|
|
|
|
await _businessRep.InsertAsync(input.Business);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
return await Get(entity.Id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 删除单据
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Ids"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[SqlSugarUnitOfWork]
|
|
|
|
|
[HttpPost("Delete")]
|
|
|
|
|
public async Task Delete(string Ids)
|
|
|
|
|
{
|
|
|
|
|
var arr = Ids.Split(",");
|
|
|
|
|
if (arr.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var ar in arr)
|
|
|
|
|
{
|
|
|
|
|
long Id = Convert.ToInt64(ar);
|
|
|
|
|
|
|
|
|
|
ExpressDeliveryOrder order = await _orderRep.AsQueryable(e => e.Id == Id).FirstAsync() ?? throw Oops.Bah("未找到快递订单");
|
|
|
|
|
|
|
|
|
|
// 添加快递动态
|
|
|
|
|
var status = new ExpressDeliveryStatus()
|
|
|
|
|
{
|
|
|
|
|
OrderId = Id,
|
|
|
|
|
MailNo = order.KDNO,
|
|
|
|
|
StatusCode = "DJY05",
|
|
|
|
|
StatusDesc = "快递单已删除"
|
|
|
|
|
};
|
|
|
|
|
await _statusRep.InsertAsync(status);
|
|
|
|
|
|
|
|
|
|
// 更新快递订单表
|
|
|
|
|
await _orderRep.UpdateAsync(x => x.Id == Id, x => new ExpressDeliveryOrder
|
|
|
|
|
{
|
|
|
|
|
IsDeleted = true,
|
|
|
|
|
CurrentStateCode = status.StatusCode,
|
|
|
|
|
CurrentStateDesc = status.StatusDesc
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 快递关联的订舱添加动态
|
|
|
|
|
List<string> mblnoList = await _businessRep.AsQueryable(x => x.PId == Id).Select(b => b.MBLNO).ToListAsync();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(mblnoList, STATUS_DELETE);
|
|
|
|
|
|
|
|
|
|
// 删除快递关联的业务表数据
|
|
|
|
|
await _businessRep.DeleteAsync(x => x.PId == Id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("请上传正确参数");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发送快递
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("SendBooking")]
|
|
|
|
|
public async Task<dynamic> SendBooking(long Id)
|
|
|
|
|
{
|
|
|
|
|
var order = _orderRep.FirstOrDefault(x => x.Id == Id);
|
|
|
|
|
if (order == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("请选择正确数据!");
|
|
|
|
|
}
|
|
|
|
|
if (order.CurrentStateCode == "DJY01")
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("下单失败,原因:尚未保存");
|
|
|
|
|
}
|
|
|
|
|
if (order.CurrentStateCode != "DJY02")
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("下单失败,原因:重复下单");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDeliverySend deliverySend = GetDeliverySend(order.KDCompany);
|
|
|
|
|
string waybillNo = await deliverySend.CreateOrder(order);
|
|
|
|
|
|
|
|
|
|
string statusDesc = $"{STATUS_SEND}(单号:{waybillNo})";
|
|
|
|
|
|
|
|
|
|
// 不需要等待的任务,并且不会因为异常导致当前请求终止
|
|
|
|
|
_ = Task.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
#region 添加快递动态
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var status = new ExpressDeliveryStatus()
|
|
|
|
|
{
|
|
|
|
|
OrderId = Id,
|
|
|
|
|
MailNo = waybillNo,
|
|
|
|
|
StatusCode = "DJY03",
|
|
|
|
|
StatusDesc = statusDesc
|
|
|
|
|
};
|
|
|
|
|
await _statusRep.InsertAsync(status);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "调用快递接口下单后,添加快递动态的过程中发生异常");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 为与快递关联的订舱添加动态
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
List<string> mblnoList = await _businessRep.AsQueryable(b => b.PId == Id).Select(b => b.MBLNO).ToListAsync();
|
|
|
|
|
_ = InsertNewBookingStatusWithMblnoList(mblnoList, statusDesc);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "调用快递接口下单后,为与快递关联的订舱添加动态的过程中发生异常");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 维护地址簿
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!await _addressRep.IsExistsAsync(a => a.People == order.SJPeople && a.Tel == order.SJTel))
|
|
|
|
|
{
|
|
|
|
|
await _addressRep.InsertAsync(new ExpressDeliveryAddress()
|
|
|
|
|
{
|
|
|
|
|
Address = order.SJAddress,
|
|
|
|
|
City = order.SJCity,
|
|
|
|
|
Company = order.SJCompany,
|
|
|
|
|
People = order.SJPeople,
|
|
|
|
|
Province = order.SJProvince,
|
|
|
|
|
ProvinceId = order.SJProvinceId,
|
|
|
|
|
Tel = order.SJTel,
|
|
|
|
|
Type = 1
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (!await _addressRep.IsExistsAsync(a => a.People == order.FJPeople && a.Tel == order.FJTel))
|
|
|
|
|
{
|
|
|
|
|
await _addressRep.InsertAsync(new ExpressDeliveryAddress()
|
|
|
|
|
{
|
|
|
|
|
Address = order.FJAddress,
|
|
|
|
|
City = order.FJCity,
|
|
|
|
|
Company = order.FJCompany,
|
|
|
|
|
People = order.FJPeople,
|
|
|
|
|
Province = order.FJProvince,
|
|
|
|
|
ProvinceId = order.FJProvinceId,
|
|
|
|
|
Tel = order.FJTel,
|
|
|
|
|
Type = 2
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "调用快递接口下单后,维护地址簿的过程中发生异常");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 需要等待的任务
|
|
|
|
|
#region 下载面单PDF,保存到本地,不会因异常终止当前请求
|
|
|
|
|
string filePath = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var dic = Path.Combine(App.WebHostEnvironment.WebRootPath, WAY_BILL_DIRECTORY);
|
|
|
|
|
if (!Directory.Exists(dic))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(dic);
|
|
|
|
|
}
|
|
|
|
|
var fileName = $"{waybillNo}_{order.Id}.pdf";
|
|
|
|
|
filePath = Path.Combine(dic, fileName);
|
|
|
|
|
|
|
|
|
|
await deliverySend.DownloadWaybillFile(waybillNo, filePath);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "调用下单接口后,下载面单的过程中发生异常");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 向快递订单表反写快递单号与状态
|
|
|
|
|
ExpressDeliveryOrder updateOrder = new ExpressDeliveryOrder()
|
|
|
|
|
{
|
|
|
|
|
Id = Id,
|
|
|
|
|
KDNO = waybillNo,
|
|
|
|
|
CurrentStateCode = "DJY03",
|
|
|
|
|
CurrentStateDesc = statusDesc,
|
|
|
|
|
WaybillFilePath = filePath
|
|
|
|
|
};
|
|
|
|
|
await _orderRep.AsUpdateable(updateOrder)
|
|
|
|
|
.UpdateColumns(o => new { o.KDNO, o.CurrentStateCode, o.CurrentStateDesc, o.WaybillFilePath })
|
|
|
|
|
.ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
UnifyContext.Fill(new
|
|
|
|
|
{
|
|
|
|
|
KDNO = waybillNo,
|
|
|
|
|
currentStateCode = "DJY03",
|
|
|
|
|
currentStateDesc = statusDesc
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return "下单成功!";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取消快递下单
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("CancelBooking")]
|
|
|
|
|
public async Task<string> CancelBooking(long Id)
|
|
|
|
|
{
|
|
|
|
|
var order = _orderRep.FirstOrDefault(x => x.Id == Id) ?? throw Oops.Bah("请选择正确数据!");
|
|
|
|
|
if (order.CurrentStateCode is "DJY01" or "DJY02")
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("消单失败,原因:尚未下单,无需消单");
|
|
|
|
|
}
|
|
|
|
|
if (order.CurrentStateCode is "DJY04")
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("消单失败,原因:已消单,无需再次消单");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDeliverySend deliverySend = GetDeliverySend(order.KDCompany);
|
|
|
|
|
await deliverySend.CancelOrder(order.Id.ToString());
|
|
|
|
|
|
|
|
|
|
#region 添加快递动态
|
|
|
|
|
var status = new ExpressDeliveryStatus()
|
|
|
|
|
{
|
|
|
|
|
OrderId = Id,
|
|
|
|
|
MailNo = order.KDNO,
|
|
|
|
|
StatusCode = "DJY04",
|
|
|
|
|
StatusDesc = STATUS_CANCEL
|
|
|
|
|
};
|
|
|
|
|
await _statusRep.InsertAsync(status);
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 为与快递关联的订舱添加动态
|
|
|
|
|
List<string> mblnoList = await _businessRep.AsQueryable(b => b.PId == Id).Select(b => b.MBLNO).ToListAsync();
|
|
|
|
|
await InsertNewBookingStatusWithMblnoList(mblnoList, STATUS_CANCEL);
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 更新快递订单状态
|
|
|
|
|
ExpressDeliveryOrder updateOrder = new ExpressDeliveryOrder()
|
|
|
|
|
{
|
|
|
|
|
Id = Id,
|
|
|
|
|
CurrentStateCode = status.StatusCode,
|
|
|
|
|
CurrentStateDesc = status.StatusDesc,
|
|
|
|
|
};
|
|
|
|
|
await _orderRep.AsUpdateable(updateOrder)
|
|
|
|
|
.UpdateColumns(o => new { o.CurrentStateCode, o.CurrentStateDesc })
|
|
|
|
|
.ExecuteCommandAsync();
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
return "取消成功!";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 打印面单(根据快递订单Id读取相应的面单文件并返回)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="authorization">Jwt令牌</param>
|
|
|
|
|
/// <param name="orderId">快递订单Id</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("PrintWaybill")]
|
|
|
|
|
[NonUnify]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<IActionResult> PrintWaybill([FromQuery][Required] string authorization, [FromQuery][Required] long orderId)
|
|
|
|
|
{
|
|
|
|
|
var validateResult = JWTEncryption.Validate(authorization);
|
|
|
|
|
if (!validateResult.IsValid)
|
|
|
|
|
{
|
|
|
|
|
return new BadPageResult(403) { Title = "接口鉴权未通过", Description = null, };
|
|
|
|
|
//return new UnauthorizedObjectResult("接口鉴权未通过");
|
|
|
|
|
}
|
|
|
|
|
var order = await _orderRep.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == orderId);
|
|
|
|
|
if (order == null)
|
|
|
|
|
{
|
|
|
|
|
return new BadPageResult(400) { Title = "请选择正确快递单", Description = null, };
|
|
|
|
|
}
|
|
|
|
|
if (order.CurrentStateCode is "DJY01" or "DJY02")
|
|
|
|
|
{
|
|
|
|
|
return new BadPageResult(400) { Title = "请先保存并下单后,再打印面单", Description = null, };
|
|
|
|
|
}
|
|
|
|
|
if (string.IsNullOrEmpty(order.KDNO))
|
|
|
|
|
{
|
|
|
|
|
return new BadPageResult(500) { Title = "未知异常:快递单号为空", Description = null, };
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var dic = Path.Combine(App.WebHostEnvironment.WebRootPath, WAY_BILL_DIRECTORY);
|
|
|
|
|
var filePath = Path.Combine(dic, order.WaybillFilePath);
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(filePath))
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("快递面单文件不存在,尝试重新下载...");
|
|
|
|
|
|
|
|
|
|
IDeliverySend deliverySend = GetDeliverySend(order.KDCompany);
|
|
|
|
|
await deliverySend.DownloadWaybillFile(order.KDNO, filePath);
|
|
|
|
|
}
|
|
|
|
|
var data = File.ReadAllBytes(filePath);
|
|
|
|
|
FileContentResult result = new FileContentResult(data, "application/pdf");
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "打印面单的过程中发生未知异常");
|
|
|
|
|
return new BadPageResult(500) { Title = "打印失败", Description = ex.Message, };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据提单号列表,向与之快递关联的订舱动态中,添加快递动态
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="mblnoList">需要添加快递动态的提单号列表</param>
|
|
|
|
|
/// <param name="status">快递动态描述</param>
|
|
|
|
|
/// <param name="logGuid">日志标志</param>
|
|
|
|
|
[NonAction]
|
|
|
|
|
private async Task InsertNewBookingStatusWithMblnoList(List<string> mblnoList, string status, string logGuid = "")
|
|
|
|
|
{
|
|
|
|
|
if (mblnoList == null || mblnoList.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"快递订单关联订舱增加动态,{logGuid},mblNoList为空,return");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_logger.LogInformation($"快递订单关联订舱增加动态,{logGuid},mblNoList:{string.Join(',', mblnoList)}");
|
|
|
|
|
List<string> filteredList = mblnoList.Where(m => !string.IsNullOrWhiteSpace(m)).ToList(); // 如果提单号为空,则不进行处理
|
|
|
|
|
if (filteredList == null || filteredList.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bookingIdMapMblnoList = await _bookingOrderRep.AsQueryable(o => o.ParentId == 0 && filteredList.Contains(o.MBLNO))
|
|
|
|
|
.Select(o => new { o.Id, o.MBLNO })
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var bookingStatusLogList = new List<BookingStatusLog>();
|
|
|
|
|
foreach (string mblNo in filteredList)
|
|
|
|
|
{
|
|
|
|
|
var bookingOrderIdListTemp = bookingIdMapMblnoList.Where(o => o.MBLNO == mblNo);
|
|
|
|
|
if (bookingOrderIdListTemp == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblNo}查询订舱记录主键结果为空,{logGuid}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (bookingOrderIdListTemp.Count() > 1)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblNo}查询订舱记录主键时查出多条记录,ids:{string.Join(',', bookingOrderIdListTemp.Select(b => b.Id).ToArray())},{logGuid}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long? bookingOrderId = bookingOrderIdListTemp.First().Id;
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblNo}查询订舱记录主键为{bookingOrderId},{logGuid}");
|
|
|
|
|
|
|
|
|
|
bookingStatusLogList.Add(new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BookingId = bookingOrderId,
|
|
|
|
|
Status = status,
|
|
|
|
|
Category = "kuaidi",
|
|
|
|
|
OpTime = DateTime.Now,
|
|
|
|
|
MBLNO = mblNo
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (bookingStatusLogList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
await _bookingStatuslogRep.InsertAsync(bookingStatusLogList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据不同的快递公司,解析出不同的实现类
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="kdCompany"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private IDeliverySend GetDeliverySend(string kdCompany)
|
|
|
|
|
{
|
|
|
|
|
return _deliverySendServiceProvider.GetService<IScoped>(kdCompany switch
|
|
|
|
|
{
|
|
|
|
|
"sf" => nameof(SFDeliverySend),
|
|
|
|
|
"jd" => throw Oops.Oh("京东快递以后会对接的"),
|
|
|
|
|
"ems" => throw Oops.Oh("EMS快递以后会对接的"),
|
|
|
|
|
_ => throw Oops.Oh("未知快递公司")
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 顺丰推送接口
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 接收顺丰推送的路由动态
|
|
|
|
|
/// </summary>
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[NonUnify]
|
|
|
|
|
[HttpPost("ReceiveSfRoute")]
|
|
|
|
|
public async Task<object> ReceiveSfRoute(SFReceiveRouteDto orderStatus)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string logGuid = Guid.NewGuid().ToString();
|
|
|
|
|
_logger.LogInformation($"接收到顺丰路由动态,{logGuid},入参:{orderStatus?.ToJsonString()}");
|
|
|
|
|
|
|
|
|
|
var expressDeliveryStatusList = new List<ExpressDeliveryStatus>();
|
|
|
|
|
foreach (WaybillRoute item in orderStatus.Body.WaybillRoute)
|
|
|
|
|
{
|
|
|
|
|
expressDeliveryStatusList.Add(new ExpressDeliveryStatus()
|
|
|
|
|
{
|
|
|
|
|
OrderId = long.Parse(item.Orderid),
|
|
|
|
|
AcceptAddress = item.AcceptAddress,
|
|
|
|
|
AcceptTime = string.IsNullOrEmpty(item.AcceptTime) ? null : DateTime.Parse(item.AcceptTime),
|
|
|
|
|
ErrorCode = item.ReasonCode,
|
|
|
|
|
ErrorDesc = item.ReasonName,
|
|
|
|
|
MailNo = item.Mailno,
|
|
|
|
|
StatusId = item.Id,
|
|
|
|
|
StatusCode = item.OpCode,
|
|
|
|
|
StatusDesc = item.Remark
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IEnumerable<IGrouping<long?, ExpressDeliveryStatus>> statusGroupList = expressDeliveryStatusList.GroupBy(e => e.OrderId);
|
|
|
|
|
foreach (IGrouping<long?, ExpressDeliveryStatus> item in statusGroupList)
|
|
|
|
|
{
|
|
|
|
|
long? orderId = item.Key;
|
|
|
|
|
|
|
|
|
|
ExpressDeliveryOrder order = await _orderRep.AsQueryable(e => e.Id == orderId)
|
|
|
|
|
.Filter(null, true)
|
|
|
|
|
.FirstAsync();
|
|
|
|
|
|
|
|
|
|
if (order == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"未找到相应的快递订单,{logGuid},Id:{orderId}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 因为此方法为匿名方法,所以需要手动设置一下租户Id
|
|
|
|
|
expressDeliveryStatusList.Where(s => s.OrderId == orderId).ToList().ForEach(e => e.TenantId = order.TenantId);
|
|
|
|
|
|
|
|
|
|
#region 更新快递订单当前的状态
|
|
|
|
|
_logger.LogInformation($"当前快递订单的状态,{logGuid},Code:{order.CurrentStateCode},Desc:{order.CurrentStateDesc}");
|
|
|
|
|
|
|
|
|
|
ExpressDeliveryStatus lastStatus = item.MaxBy(e => e.StatusId);
|
|
|
|
|
Lazy<IUpdateable<ExpressDeliveryOrder>> waitUpdate = new(() => _orderRep.Context.Updateable<ExpressDeliveryOrder>());
|
|
|
|
|
if (order.CurrentStateCode != lastStatus.StatusCode)
|
|
|
|
|
{
|
|
|
|
|
waitUpdate.Value.SetColumns(o => o.CurrentStateCode == lastStatus.StatusCode);
|
|
|
|
|
}
|
|
|
|
|
if (order.CurrentStateDesc != lastStatus.StatusDesc)
|
|
|
|
|
{
|
|
|
|
|
waitUpdate.Value.SetColumns(o => o.CurrentStateDesc == lastStatus.StatusDesc);
|
|
|
|
|
}
|
|
|
|
|
if (waitUpdate.IsValueCreated)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"快递订单的状态更新为,{logGuid},Code:{lastStatus.StatusCode},Desc:{lastStatus.StatusDesc}");
|
|
|
|
|
await waitUpdate.Value.Where(e => e.Id == orderId).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 向与快递关联的订舱列表中添加动态(如果一票快递关联了多条订舱,则每条订舱都要添加动态)
|
|
|
|
|
List<string> mblNoList = await _businessRep.AsQueryable(b => b.PId == orderId && b.TenantId == order.TenantId).Filter(null, true).Select(b => b.MBLNO).ToListAsync();
|
|
|
|
|
List<string> filteredList = mblNoList.Where(m => !string.IsNullOrWhiteSpace(m)).ToList();
|
|
|
|
|
|
|
|
|
|
if (filteredList == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据快递订单主键查询关联业务表的提单号,查询结果为空,{logGuid}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据快递订单主键查询关联业务表的提单号,共查出以下记录,MblNos:{string.Join(',', filteredList)},{logGuid}");
|
|
|
|
|
|
|
|
|
|
var bookingIdMapMblnoList = await _bookingOrderRep.AsQueryable(o => o.ParentId == 0 && o.TenantId == order.TenantId && filteredList.Contains(o.MBLNO))
|
|
|
|
|
.Filter(null, true)
|
|
|
|
|
.Select(o => new { o.Id, o.MBLNO })
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var bookingStatusLogList = new List<BookingStatusLog>();
|
|
|
|
|
foreach (string mblnoItem in filteredList)
|
|
|
|
|
{
|
|
|
|
|
var bookingOrderIdListTemp = bookingIdMapMblnoList.Where(o => o.MBLNO == mblnoItem);
|
|
|
|
|
if (bookingOrderIdListTemp == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblnoItem}查询订舱记录主键结果为空,{logGuid}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (bookingOrderIdListTemp.Count() > 1)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblnoItem}查询订舱记录主键时查出多条记录,ids:{string.Join(',', bookingOrderIdListTemp.Select(b => b.Id).ToArray())},{logGuid}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long? bookingOrderId = bookingOrderIdListTemp.First().Id;
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblnoItem}查询订舱记录主键为{bookingOrderId},{logGuid}");
|
|
|
|
|
|
|
|
|
|
foreach (ExpressDeliveryStatus statusItem in item)
|
|
|
|
|
{
|
|
|
|
|
bookingStatusLogList.Add(new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BookingId = bookingOrderId,
|
|
|
|
|
Status = statusItem.StatusDesc,
|
|
|
|
|
Category = "kuaidi",
|
|
|
|
|
OpTime = DateTime.Now,
|
|
|
|
|
MBLNO = bookingOrderIdListTemp.First().MBLNO,
|
|
|
|
|
TenantId = order.TenantId
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await _bookingStatuslogRep.InsertAsync(bookingStatusLogList);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 保存快递动态
|
|
|
|
|
// 如果租户Id不为null或0,说明接收到的快递动态能找到相应的快递订单,然后再进行动态新增操作
|
|
|
|
|
expressDeliveryStatusList = expressDeliveryStatusList.Where(e => e.TenantId != null && e.TenantId != 0).ToList();
|
|
|
|
|
if (expressDeliveryStatusList != null && expressDeliveryStatusList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
await _statusRep.InsertAsync(expressDeliveryStatusList);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
return new { return_code = "0000", return_msg = "成功" };
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "接收顺丰推送的路由状态时发生异常");
|
|
|
|
|
return new { return_code = "1000", return_msg = ex.Message };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 接收顺丰推送的订单动态
|
|
|
|
|
/// </summary>
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[NonUnify]
|
|
|
|
|
[HttpPost("ReceiveSfOrderState")]
|
|
|
|
|
public async Task<object> ReceiveSfOrderState(ReceiveSfOrderStateDto receive)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string logGuid = Guid.NewGuid().ToString();
|
|
|
|
|
_logger.LogInformation($"接收到顺丰快递动态,{logGuid},入参:{receive?.ToJsonString()}");
|
|
|
|
|
|
|
|
|
|
var expressDeliveryStatusList = new List<ExpressDeliveryStatus>();
|
|
|
|
|
foreach (ReceiveSfOrderStateDto.OrderState item in receive.orderState)
|
|
|
|
|
{
|
|
|
|
|
expressDeliveryStatusList.Add(new ExpressDeliveryStatus()
|
|
|
|
|
{
|
|
|
|
|
OrderId = long.Parse(item.orderNo),
|
|
|
|
|
AcceptAddress = "",
|
|
|
|
|
AcceptTime = null,
|
|
|
|
|
ErrorCode = "",
|
|
|
|
|
ErrorDesc = "",
|
|
|
|
|
MailNo = item.waybillNo,
|
|
|
|
|
StatusId = receive.requestId,
|
|
|
|
|
StatusCode = item.orderStateCode,
|
|
|
|
|
StatusDesc = item.orderStateDesc
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IEnumerable<IGrouping<long?, ExpressDeliveryStatus>> statusGroupList = expressDeliveryStatusList.GroupBy(e => e.OrderId);
|
|
|
|
|
foreach (IGrouping<long?, ExpressDeliveryStatus> item in statusGroupList)
|
|
|
|
|
{
|
|
|
|
|
long? orderId = item.Key;
|
|
|
|
|
|
|
|
|
|
ExpressDeliveryOrder order = await _orderRep.AsQueryable(e => e.Id == orderId)
|
|
|
|
|
.Filter(null, true)
|
|
|
|
|
.FirstAsync();
|
|
|
|
|
|
|
|
|
|
if (order == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"未找到相应的快递订单,{logGuid},Id:{orderId}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 因为此方法为匿名方法,所以需要手动设置一下租户Id
|
|
|
|
|
expressDeliveryStatusList.Where(s => s.OrderId == orderId).ToList().ForEach(e => e.TenantId = order.TenantId);
|
|
|
|
|
|
|
|
|
|
#region 更新快递订单当前的状态
|
|
|
|
|
_logger.LogInformation($"当前快递订单的状态,{logGuid},Code:{order.CurrentStateCode},Desc:{order.CurrentStateDesc}");
|
|
|
|
|
|
|
|
|
|
ExpressDeliveryStatus lastStatus = item.MaxBy(e => e.StatusId);
|
|
|
|
|
Lazy<IUpdateable<ExpressDeliveryOrder>> waitUpdate = new(() => _orderRep.Context.Updateable<ExpressDeliveryOrder>());
|
|
|
|
|
if (order.CurrentStateCode != lastStatus.StatusCode)
|
|
|
|
|
{
|
|
|
|
|
waitUpdate.Value.SetColumns(o => o.CurrentStateCode == lastStatus.StatusCode);
|
|
|
|
|
}
|
|
|
|
|
if (order.CurrentStateDesc != lastStatus.StatusDesc)
|
|
|
|
|
{
|
|
|
|
|
waitUpdate.Value.SetColumns(o => o.CurrentStateDesc == lastStatus.StatusDesc);
|
|
|
|
|
}
|
|
|
|
|
if (waitUpdate.IsValueCreated)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"快递订单的状态更新为,{logGuid},Code:{lastStatus.StatusCode},Desc:{lastStatus.StatusDesc}");
|
|
|
|
|
await waitUpdate.Value.Where(e => e.Id == orderId).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 向与快递关联的订舱列表中添加动态(如果一票快递关联了多条订舱,则每条订舱都要添加动态)
|
|
|
|
|
List<string> mblNoList = await _businessRep.AsQueryable(b => b.PId == orderId && b.TenantId == order.TenantId).Filter(null, true).Select(b => b.MBLNO).ToListAsync();
|
|
|
|
|
List<string> filteredList = mblNoList.Where(m => !string.IsNullOrWhiteSpace(m)).ToList();
|
|
|
|
|
|
|
|
|
|
if (filteredList == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据快递订单主键查询关联业务表的提单号,查询结果为空,{logGuid}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据快递订单主键查询关联业务表的提单号,共查出以下记录,MblNos:{string.Join(',', filteredList)},{logGuid}");
|
|
|
|
|
|
|
|
|
|
var bookingIdMapMblnoList = await _bookingOrderRep.AsQueryable(o => o.ParentId == 0 && o.TenantId == order.TenantId && filteredList.Contains(o.MBLNO))
|
|
|
|
|
.Filter(null, true)
|
|
|
|
|
.Select(o => new { o.Id, o.MBLNO })
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var bookingStatusLogList = new List<BookingStatusLog>();
|
|
|
|
|
foreach (string mblnoItem in filteredList)
|
|
|
|
|
{
|
|
|
|
|
var bookingOrderIdListTemp = bookingIdMapMblnoList.Where(o => o.MBLNO == mblnoItem);
|
|
|
|
|
if (bookingOrderIdListTemp == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblnoItem}查询订舱记录主键结果为空,{logGuid}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (bookingOrderIdListTemp.Count() > 1)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblnoItem}查询订舱记录主键时查出多条记录,ids:{string.Join(',', bookingOrderIdListTemp.Select(b => b.Id).ToArray())},{logGuid}");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long? bookingOrderId = bookingOrderIdListTemp.First().Id;
|
|
|
|
|
_logger.LogInformation($"根据提单号{mblnoItem}查询订舱记录主键为{bookingOrderId},{logGuid}");
|
|
|
|
|
|
|
|
|
|
foreach (ExpressDeliveryStatus statusItem in item)
|
|
|
|
|
{
|
|
|
|
|
bookingStatusLogList.Add(new BookingStatusLog()
|
|
|
|
|
{
|
|
|
|
|
BookingId = bookingOrderId,
|
|
|
|
|
Status = statusItem.StatusDesc,
|
|
|
|
|
Category = "kuaidi",
|
|
|
|
|
OpTime = DateTime.Now,
|
|
|
|
|
MBLNO = bookingOrderIdListTemp.First().MBLNO,
|
|
|
|
|
TenantId = order.TenantId
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
await _bookingStatuslogRep.InsertAsync(bookingStatusLogList);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 保存快递动态
|
|
|
|
|
// 如果租户Id不为null或0,说明接收到的快递动态能找到相应的快递订单,然后再进行动态新增操作
|
|
|
|
|
expressDeliveryStatusList = expressDeliveryStatusList.Where(e => e.TenantId != null && e.TenantId != 0).ToList();
|
|
|
|
|
if (expressDeliveryStatusList != null && expressDeliveryStatusList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
await _statusRep.InsertAsync(expressDeliveryStatusList);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
return new { success = "true", code = "0", msg = "" };
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "接收顺丰推送的订单状态时发生异常");
|
|
|
|
|
return new { success = "false", code = "0", msg = ex.Message };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 接收顺丰推送的费用信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[NonUnify]
|
|
|
|
|
[HttpPost("ReceiveSfFee")]
|
|
|
|
|
[HttpGet("ReceiveSfFee")]
|
|
|
|
|
public async Task<object> ReceiveSfFee([FromForm] ReceiveSfFeeDto receive)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string logGuid = Guid.NewGuid().ToString();
|
|
|
|
|
_logger.LogInformation($"接收到顺丰快递费用信息,{logGuid},入参:{receive?.ToJsonString()}");
|
|
|
|
|
|
|
|
|
|
ContentModel content = JsonConvert.DeserializeObject<ContentModel>(receive.content);
|
|
|
|
|
|
|
|
|
|
long orderId = long.Parse(content.orderNo);
|
|
|
|
|
ExpressDeliveryOrder order = await _orderRep.AsQueryable(e => e.Id == orderId)
|
|
|
|
|
.Filter(null, true)
|
|
|
|
|
.FirstAsync();
|
|
|
|
|
|
|
|
|
|
if (order == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation($"未找到相应的快递订单,{logGuid},Id:{orderId}");
|
|
|
|
|
return new { code = "200", partnerCode = "", service = "", msgData = "" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存计费重量
|
|
|
|
|
var feeWeight = float.Parse(content.meterageWeightQty);
|
|
|
|
|
await _orderRep.Context.Updateable<ExpressDeliveryOrder>()
|
|
|
|
|
.SetColumns(o => o.FeeWeight == feeWeight + "(kg)")
|
|
|
|
|
.Where(e => e.Id == orderId)
|
|
|
|
|
.ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
List<ExpressDeliveryFee> feeList = new(content.feeList.Count);
|
|
|
|
|
|
|
|
|
|
// 保存费用信息
|
|
|
|
|
foreach (Fee item in content.feeList)
|
|
|
|
|
{
|
|
|
|
|
feeList.Add(new ExpressDeliveryFee()
|
|
|
|
|
{
|
|
|
|
|
Account = item.customerAcctCode,
|
|
|
|
|
FeeAmount = item.feeAmt,
|
|
|
|
|
FeeTypeCode = item.feeTypeCode,
|
|
|
|
|
FeeTypeName = item.feeTypeCode switch { "1" => "主运费", "2" => "其他费用", "3" => "保费", "4" => "代收货款服务费", "5" => "代收货款", _ => "未知费用类型" },
|
|
|
|
|
KDNO = item.waybillNo,
|
|
|
|
|
OrderId = orderId,
|
|
|
|
|
SettleAccountsTypeCode = item.settlementTypeCode
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// 因为此方法为匿名方法,所以需要手动设置一下租户Id
|
|
|
|
|
feeList.Where(s => s.OrderId == orderId).ToList().ForEach(e => e.TenantId = order.TenantId);
|
|
|
|
|
await _feeRep.InsertAsync(feeList);
|
|
|
|
|
|
|
|
|
|
return new { code = "200", partnerCode = "", service = "", msgData = "" };
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "接收顺丰推送的费用信息时发生异常");
|
|
|
|
|
return new { code = "400", partnerCode = "", service = "", msgData = "" };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 地址簿相关
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取快递地址簿列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
[HttpGet("GetAddressList")]
|
|
|
|
|
public async Task<List<ExpressDeliveryAddressDto>> GetAddressList()
|
|
|
|
|
{
|
|
|
|
|
var modelList = await _addressRep.ToListAsync(e => true, e => e.Type, OrderByType.Desc);
|
|
|
|
|
var result = modelList.Adapt<List<ExpressDeliveryAddressDto>>();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 删除快递地址簿
|
|
|
|
|
/// </summary>
|
|
|
|
|
[HttpPost("DeleteAddress")]
|
|
|
|
|
public async Task DeleteAddress([Required] string ids)
|
|
|
|
|
{
|
|
|
|
|
long[] idArr = ids.Split(',').Adapt<long[]>();
|
|
|
|
|
await _addressRep.DeleteAsync(a => idArr.Contains(a.Id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 新增或修改地址簿
|
|
|
|
|
/// </summary>
|
|
|
|
|
[HttpPost("SaveOrUpdateAddress")]
|
|
|
|
|
public async Task SaveOrUpdateAddress(ExpressDeliveryAddressDto input)
|
|
|
|
|
{
|
|
|
|
|
if (input == null) return;
|
|
|
|
|
var inputModel = input.Adapt<ExpressDeliveryAddress>();
|
|
|
|
|
|
|
|
|
|
if (inputModel.Id == 0)
|
|
|
|
|
{
|
|
|
|
|
await _addressRep.InsertAsync(inputModel);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await _addressRep.AsUpdateable(inputModel)
|
|
|
|
|
.IgnoreColumns(a => a.TenantId)
|
|
|
|
|
.ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|