|
|
using Furion;
|
|
|
using Furion.EventBus;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.JsonPatch.Internal;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application.ConfigOption;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Application.Service.BookingOrder.Dto;
|
|
|
using Myshipping.Core;
|
|
|
using Myshipping.Core.Entity;
|
|
|
using Myshipping.Core.Helper;
|
|
|
using Myshipping.Core.Service;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using NPOI.SS.Formula.PTG;
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net.Http;
|
|
|
using System.Security.Policy;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
using Yitter.IdGenerator;
|
|
|
|
|
|
namespace Myshipping.Application.Event
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 扣费
|
|
|
/// </summary>
|
|
|
public class BookingFeeSubscriber : IEventSubscriber
|
|
|
{
|
|
|
private IServiceProvider _services { get; }
|
|
|
private readonly ILogger<BookingFeeSubscriber> _logger;
|
|
|
|
|
|
public BookingFeeSubscriber(IServiceProvider services
|
|
|
, ILogger<BookingFeeSubscriber> logger)
|
|
|
{
|
|
|
_services = services;
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
//扣费
|
|
|
[EventSubscribe("Booking:DoFeeRecord")]
|
|
|
public async Task DoFeeRecord(EventHandlerExecutingContext context)
|
|
|
{
|
|
|
_logger.LogInformation($"收到订舱扣费请求:{context.Source.Payload}");
|
|
|
|
|
|
var paraObj = context.Source.Payload as dynamic;
|
|
|
|
|
|
int bsType = paraObj.bsType;
|
|
|
int sendType = paraObj.sendtype;
|
|
|
List<long> idList = paraObj.idList;
|
|
|
idList = idList.Distinct().ToList();
|
|
|
|
|
|
_logger.LogInformation($"准备处理扣费,bsType:{bsType},sendType:{sendType},id列表:{string.Join(',', idList)}");
|
|
|
|
|
|
using var scope = _services.CreateScope();
|
|
|
|
|
|
var repoUser = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<SysUser>>();
|
|
|
var repoBooking = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingOrder>>();
|
|
|
var repoFeeRecord = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<BookingFeeRecord>>();
|
|
|
var repoTenantParamValue = scope.ServiceProvider.GetRequiredService<SqlSugarRepository<DjyTenantParamValue>>();
|
|
|
var cache = scope.ServiceProvider.GetRequiredService<ISysCacheService>();
|
|
|
|
|
|
var feeOrderList = await repoBooking
|
|
|
.AsQueryable()
|
|
|
.Filter(null, true)
|
|
|
.Where(x => idList.Contains(x.Id))
|
|
|
.Select(x => new { x.Id, x.MBLNO, x.OPID, x.CreatedUserId, x.TenantId })
|
|
|
.ToListAsync();
|
|
|
|
|
|
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);
|
|
|
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
foreach (var order in feeOrderList)
|
|
|
{
|
|
|
var iptId = string.IsNullOrEmpty(order.OPID) ? order.CreatedUserId.Value : Convert.ToInt64(order.OPID);
|
|
|
var user = await repoUser.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == iptId);
|
|
|
var keyList = await repoTenantParamValue.AsQueryable()
|
|
|
.Filter(null, true)
|
|
|
.Where(x => x.TenantId == order.TenantId && (x.ParaCode == "BOOKING_FEE_USERID" || x.ParaCode == "BOOKING_FEE_USERKEY"))
|
|
|
.ToListAsync();
|
|
|
if (keyList.Count < 2)
|
|
|
{
|
|
|
var errMsg = $"未找到{order.MBLNO}({order.Id})所在租户的授权userid和key,无法调用扣费";
|
|
|
_logger.LogError(errMsg);
|
|
|
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
|
|
|
continue;
|
|
|
}
|
|
|
var feeUserId = keyList.First(x => x.ParaCode == "BOOKING_FEE_USERID").ItemCode;
|
|
|
var feeUserKey = keyList.First(x => x.ParaCode == "BOOKING_FEE_USERKEY").ItemCode;
|
|
|
|
|
|
|
|
|
if (user == null || string.IsNullOrEmpty(user.DjyUserId))
|
|
|
{
|
|
|
var errMsg = $"未找到{order.MBLNO}({order.Id})的用户信息,无法调用扣费";
|
|
|
_logger.LogError(errMsg);
|
|
|
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
var c = repoFeeRecord.AsQueryable().Filter(null, true).Count(x => x.TenantId == order.TenantId && x.MBLNO == order.MBLNO);
|
|
|
if (c > 0)
|
|
|
{
|
|
|
_logger.LogInformation($"已存在扣费记录,id:{order.Id},提单号:{order.MBLNO},租户:{order.TenantId}");
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
var seconds = DateTime.Now.ToTimeStamp();
|
|
|
var runId = Guid.NewGuid().ToString();
|
|
|
var srcBeforMD5 = $"{runId}{feeUserId}expend{bsType}{sendType}{order.Id}{order.MBLNO}{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 = order.Id.ToString(),
|
|
|
MBLNO = order.MBLNO,
|
|
|
CtnrInfo = "",
|
|
|
CtnrCount = 1,
|
|
|
IsCredit = 1,//是否是信用支付 1 信用支付 0不允许信用支付默认值为0,
|
|
|
LURURENID = user.DjyUserId,
|
|
|
SENDUSERID = user.DjyUserId
|
|
|
}
|
|
|
};
|
|
|
|
|
|
_logger.LogInformation($"调用扣费:{postObj.ToJsonString()}");
|
|
|
var apiRtn = await feeUrl.Value
|
|
|
.SetHttpMethod(HttpMethod.Post)
|
|
|
.SetBody(postObj)
|
|
|
.SetRetryPolicy(3, 5000)
|
|
|
.OnException((c, m, errMsg) =>
|
|
|
{
|
|
|
_logger.LogError($"扣费失败:{errMsg}");
|
|
|
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", 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 = order.Id;
|
|
|
fr.MBLNO = order.MBLNO;
|
|
|
fr.TenantId = order.TenantId.Value;
|
|
|
fr.Type = typeStr;
|
|
|
fr.Amount = total;
|
|
|
await repoFeeRecord.InsertAsync(fr);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var errMsg = jobjApiRtn.GetValue("message").ToString();
|
|
|
_logger.LogError($"扣费失败:{errMsg}");
|
|
|
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
_logger.LogInformation($"扣费处理完成");
|
|
|
}
|
|
|
}
|
|
|
}
|