|
|
@ -3,6 +3,7 @@ using Furion.DependencyInjection;
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
using Furion.EventBus;
|
|
|
|
using Furion.EventBus;
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
|
|
|
using Furion.LinqBuilder;
|
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
|
using Mapster;
|
|
|
|
using Mapster;
|
|
|
|
using MathNet.Numerics.LinearAlgebra.Factorization;
|
|
|
|
using MathNet.Numerics.LinearAlgebra.Factorization;
|
|
|
@ -28,8 +29,10 @@ using RabbitMQ.Client;
|
|
|
|
using System;
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Data;
|
|
|
|
using System.Data;
|
|
|
|
|
|
|
|
using System.Drawing.Drawing2D;
|
|
|
|
using System.IO;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
using System.Net.Http;
|
|
|
|
using System.Text;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Yitter.IdGenerator;
|
|
|
|
using Yitter.IdGenerator;
|
|
|
@ -63,6 +66,8 @@ namespace Myshipping.Application
|
|
|
|
private readonly IBookingOrderService bookingOrderService;
|
|
|
|
private readonly IBookingOrderService bookingOrderService;
|
|
|
|
private readonly SqlSugarRepository<DjyCustomer> _repCustomer;
|
|
|
|
private readonly SqlSugarRepository<DjyCustomer> _repCustomer;
|
|
|
|
private readonly SqlSugarRepository<DjyCustomerParamValue> _repCustomerParamValue;
|
|
|
|
private readonly SqlSugarRepository<DjyCustomerParamValue> _repCustomerParamValue;
|
|
|
|
|
|
|
|
private readonly SqlSugarRepository<DjyCustomerContact> _repCustomerContact;
|
|
|
|
|
|
|
|
private readonly SqlSugarRepository<BookingFeeRecord> _repFeeRecord;
|
|
|
|
|
|
|
|
|
|
|
|
public BookingCustomerOrderService(SqlSugarRepository<BookingCustomerOrder> rep, SqlSugarRepository<BookingCtn> repCtn,
|
|
|
|
public BookingCustomerOrderService(SqlSugarRepository<BookingCustomerOrder> rep, SqlSugarRepository<BookingCtn> repCtn,
|
|
|
|
ILogger<BookingOrderService> logger, ISysCacheService cache, SqlSugarRepository<BookingFile> repFile,
|
|
|
|
ILogger<BookingOrderService> logger, ISysCacheService cache, SqlSugarRepository<BookingFile> repFile,
|
|
|
@ -71,7 +76,8 @@ namespace Myshipping.Application
|
|
|
|
SqlSugarRepository<BookingCustomerOrderTemplate> repOrderTempl,
|
|
|
|
SqlSugarRepository<BookingCustomerOrderTemplate> repOrderTempl,
|
|
|
|
SqlSugarRepository<BookingEDIExt> repEdiExt, SqlSugarRepository<BookingGoodsStatus> goodsStatus, SqlSugarRepository<BookingGoodsStatusConfig> goodsStatusConfig,
|
|
|
|
SqlSugarRepository<BookingEDIExt> repEdiExt, SqlSugarRepository<BookingGoodsStatus> goodsStatus, SqlSugarRepository<BookingGoodsStatusConfig> goodsStatusConfig,
|
|
|
|
IEventPublisher publisher, SqlSugarRepository<DjyApiAuth> repApiAuth, SqlSugarRepository<DjyMessage> repMessage, IBookingOrderService bookingOrderService,
|
|
|
|
IEventPublisher publisher, SqlSugarRepository<DjyApiAuth> repApiAuth, SqlSugarRepository<DjyMessage> repMessage, IBookingOrderService bookingOrderService,
|
|
|
|
SqlSugarRepository<DjyCustomer> repCustomer, SqlSugarRepository<DjyCustomerParamValue> repCustomerParamValue)
|
|
|
|
SqlSugarRepository<DjyCustomer> repCustomer, SqlSugarRepository<DjyCustomerParamValue> repCustomerParamValue, SqlSugarRepository<DjyCustomerContact> repCustomerContact,
|
|
|
|
|
|
|
|
SqlSugarRepository<BookingFeeRecord> repFeeRecord)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
this._logger = logger;
|
|
|
|
this._logger = logger;
|
|
|
|
this._rep = rep;
|
|
|
|
this._rep = rep;
|
|
|
@ -92,6 +98,8 @@ namespace Myshipping.Application
|
|
|
|
this.bookingOrderService = bookingOrderService;
|
|
|
|
this.bookingOrderService = bookingOrderService;
|
|
|
|
this._repCustomer = repCustomer;
|
|
|
|
this._repCustomer = repCustomer;
|
|
|
|
this._repCustomerParamValue = repCustomerParamValue;
|
|
|
|
this._repCustomerParamValue = repCustomerParamValue;
|
|
|
|
|
|
|
|
this._repCustomerContact = repCustomerContact;
|
|
|
|
|
|
|
|
this._repFeeRecord = repFeeRecord;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region 订舱草稿及附件
|
|
|
|
#region 订舱草稿及附件
|
|
|
@ -1839,6 +1847,9 @@ namespace Myshipping.Application
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//扣费
|
|
|
|
|
|
|
|
await FeeSo(model.Id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1969,6 +1980,15 @@ namespace Myshipping.Application
|
|
|
|
await _publisher.PublishAsync(new ChannelEventSource("Message:NotifyReceiveNew"));
|
|
|
|
await _publisher.PublishAsync(new ChannelEventSource("Message:NotifyReceiveNew"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// 扣费
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
|
|
[HttpPost("/BookingCustomerOrder/DoFee")]
|
|
|
|
|
|
|
|
public async Task DoFee(long custOrdId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
await FeeSo(custOrdId);
|
|
|
|
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 私有方法
|
|
|
|
#region 私有方法
|
|
|
@ -2007,6 +2027,126 @@ namespace Myshipping.Application
|
|
|
|
staLog.Remark = remark;
|
|
|
|
staLog.Remark = remark;
|
|
|
|
_repStatuslog.Insert(staLog);
|
|
|
|
_repStatuslog.Insert(staLog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// 订舱审核后自动扣费
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
|
|
private async Task FeeSo(long id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var model = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == id);
|
|
|
|
|
|
|
|
var cust = await _repCustomer.AsQueryable().Filter(null, true).FirstAsync(x => x.CustSysId == model.BookingTenantId);
|
|
|
|
|
|
|
|
var custParaList = await _repCustomerParamValue.AsQueryable().Filter(null, true).Where(x => x.CustomerId == cust.Id && (x.ParaCode == "DjyFeeApiUserId" || x.ParaCode == "DjyFeeApiUserSecret")).ToListAsync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var bsType = 32;
|
|
|
|
|
|
|
|
var sendType = 0;
|
|
|
|
|
|
|
|
var typeStr = $"{bsType}_{sendType}";
|
|
|
|
|
|
|
|
var sysCfg = await _cache.GetAllSysConfig();
|
|
|
|
|
|
|
|
var feeUrl = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiUrl");
|
|
|
|
|
|
|
|
if (feeUrl == null || string.IsNullOrEmpty(feeUrl.Value))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var errMsg = "大简云扣费URL未配置";
|
|
|
|
|
|
|
|
_logger.LogError(errMsg);
|
|
|
|
|
|
|
|
SaveAuditLog($"扣费失败", model.Id, model.CreatedUserId.Value, model.TenantId.Value, "系统", remark: errMsg);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//扣费接口用户id和key
|
|
|
|
|
|
|
|
var feeUserId = custParaList.FirstOrDefault(x => x.ParaCode == "DjyFeeApiUserId")?.ItemCode;
|
|
|
|
|
|
|
|
var feeUserKey = custParaList.FirstOrDefault(x => x.ParaCode == "DjyFeeApiUserSecret")?.ItemCode;
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(feeUserId) || string.IsNullOrEmpty(feeUserKey))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var errMsg = $"未找到{model.BOOKINGNO}({model.Id})所在客户的授权userid和key,无法调用扣费";
|
|
|
|
|
|
|
|
_logger.LogError(errMsg);
|
|
|
|
|
|
|
|
SaveAuditLog($"扣费失败", model.Id, model.CreatedUserId.Value, model.TenantId.Value, "系统", remark: "未找到扣费接口授权信息");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//判断重复扣费
|
|
|
|
|
|
|
|
var c = _repFeeRecord.AsQueryable().Filter(null, true).Count(x => x.TenantId == model.BookingTenantId && x.MBLNO == model.BOOKINGNO);
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_logger.LogInformation($"已存在扣费记录,id:{model.Id},订舱号:{model.BOOKINGNO},租户:{model.BookingTenantId}");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//客户联系人
|
|
|
|
|
|
|
|
var contact = await _repCustomerContact.AsQueryable().Filter(null, true).FirstAsync(x => x.CustSysId == model.BookingUserId);
|
|
|
|
|
|
|
|
if (contact == null)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var errMsg = $"未找到{model.BOOKINGNO}({model.Id})的客户联系人";
|
|
|
|
|
|
|
|
_logger.LogError(errMsg);
|
|
|
|
|
|
|
|
SaveAuditLog($"扣费失败", model.Id, model.CreatedUserId.Value, model.TenantId.Value, "系统", remark: "未找到客户联系人");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//扣费dto
|
|
|
|
|
|
|
|
var seconds = DateTime.Now.ToTimeStamp();
|
|
|
|
|
|
|
|
var runId = Guid.NewGuid().ToString();
|
|
|
|
|
|
|
|
var srcBeforMD5 = $"{runId}{feeUserId}expend{bsType}{sendType}{model.Id}{model.BOOKINGNO}{seconds}{feeUserKey}";
|
|
|
|
|
|
|
|
var postObj = new
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
runId,
|
|
|
|
|
|
|
|
userId = feeUserId,
|
|
|
|
|
|
|
|
module = "expend",//固定
|
|
|
|
|
|
|
|
bsType = $"{bsType}",
|
|
|
|
|
|
|
|
sendType = $"{sendType}",
|
|
|
|
|
|
|
|
timestamp = seconds,//秒级时间戳
|
|
|
|
|
|
|
|
md5 = srcBeforMD5.ToMd5(),// 加密字符串小写 RunId + UserId + Module + BsType + SendType+Timestamp+ Key
|
|
|
|
|
|
|
|
Data = new
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
BSNO = model.Id.ToString(),
|
|
|
|
|
|
|
|
MBLNO = model.BOOKINGNO,
|
|
|
|
|
|
|
|
CtnrInfo = "",
|
|
|
|
|
|
|
|
CtnrCount = 1,
|
|
|
|
|
|
|
|
IsCredit = 0,//是否是信用支付 1 信用支付 0不允许信用支付默认值为0,
|
|
|
|
|
|
|
|
LURURENID = contact.DjyGid,
|
|
|
|
|
|
|
|
SENDUSERID = contact.DjyGid,
|
|
|
|
|
|
|
|
VESSEL = model.VESSEL,
|
|
|
|
|
|
|
|
VOYNO = model.VOYNO,
|
|
|
|
|
|
|
|
ETD = model.ETD,
|
|
|
|
|
|
|
|
CARRIER = model.CARRIER
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"调用扣费:{postObj.ToJsonString()}");
|
|
|
|
|
|
|
|
var apiRtn = await feeUrl.Value
|
|
|
|
|
|
|
|
.SetHttpMethod(HttpMethod.Post)
|
|
|
|
|
|
|
|
.SetBody(postObj)
|
|
|
|
|
|
|
|
.SetRetryPolicy(3, 5000)
|
|
|
|
|
|
|
|
.OnException((c, m, errMsg) =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_logger.LogError($"扣费失败:{errMsg}");
|
|
|
|
|
|
|
|
SaveAuditLog($"扣费失败", model.Id, model.CreatedUserId.Value, model.TenantId.Value, "系统", remark: errMsg);
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.SendAsStringAsync();
|
|
|
|
|
|
|
|
_logger.LogInformation($"调用扣费返回:{apiRtn}");
|
|
|
|
|
|
|
|
var jobjApiRtn = JObject.Parse(apiRtn);
|
|
|
|
|
|
|
|
var code = jobjApiRtn.GetIntValue("code");
|
|
|
|
|
|
|
|
var jobjApiRtnData = jobjApiRtn.GetValue("data") as JObject;
|
|
|
|
|
|
|
|
if (code == 200 || code == 450)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var jobjApiRtnDataPayInfo = jobjApiRtnData.GetValue("payInfo") as JObject;
|
|
|
|
|
|
|
|
var price = Convert.ToDecimal(jobjApiRtnDataPayInfo.GetValue("price").ToString());
|
|
|
|
|
|
|
|
var total = Convert.ToDecimal(jobjApiRtnDataPayInfo.GetValue("total").ToString());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//记录扣费
|
|
|
|
|
|
|
|
var fr = new BookingFeeRecord();
|
|
|
|
|
|
|
|
fr.Id = YitIdHelper.NextId();
|
|
|
|
|
|
|
|
fr.BillId = model.Id;
|
|
|
|
|
|
|
|
fr.MBLNO = model.BOOKINGNO;
|
|
|
|
|
|
|
|
fr.TenantId = model.BookingTenantId;
|
|
|
|
|
|
|
|
fr.Type = typeStr;
|
|
|
|
|
|
|
|
fr.Amount = total;
|
|
|
|
|
|
|
|
await _repFeeRecord.InsertAsync(fr);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var errMsg = jobjApiRtn.GetValue("message").ToString();
|
|
|
|
|
|
|
|
_logger.LogError($"扣费失败:{errMsg}");
|
|
|
|
|
|
|
|
SaveAuditLog($"扣费失败", model.Id, model.CreatedUserId.Value, model.TenantId.Value, "系统", remark: errMsg);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 外部开放接口
|
|
|
|
#region 外部开放接口
|
|
|
|