You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookingHeChuan/Myshipping.Application/Event/BookingFeeSubscriber.cs

167 lines
7.3 KiB
C#

9 months ago
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 cache = scope.ServiceProvider.GetRequiredService<ISysCacheService>();
var typeStr = $"{bsType}_{sendType}";
var dbFeeRecord = repoFeeRecord.AsQueryable().Where(x => x.Type == typeStr && idList.Contains(x.BillId)).Select(x => x.BillId).ToList();
var idToDo = idList.Except(dbFeeRecord).ToList();
var sysCfg = await cache.GetAllSysConfig();
var feeUrl = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiUrl");
var feeUserId = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiUserId");
var feeKey = sysCfg.FirstOrDefault(x => x.Code == "djyFeeApiKey");
if (feeKey == null || string.IsNullOrEmpty(feeUrl.Value)
|| feeUserId == null || string.IsNullOrEmpty(feeUserId.Value)
|| feeKey == null || string.IsNullOrEmpty(feeKey.Value))
{
var errMsg = "大简云扣费URL和KEY未配置";
_logger.LogError(errMsg);
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
return;
}
foreach (var id in idToDo)
{
var order = await repoBooking.AsQueryable().FirstAsync(x => x.Id == id);
var iptId = string.IsNullOrEmpty(order.OPID) ? order.CreatedUserId.Value : Convert.ToInt64(order.OPID);
var user = await repoUser.AsQueryable().FirstAsync(x => x.Id == iptId);
if (user == null || string.IsNullOrEmpty(user.DjyUserId))
{
var errMsg = $"未找到{order.MBLNO}({id})的用户信息,无法调用扣费";
_logger.LogError(errMsg);
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
continue;
}
var seconds = DateTime.Now.ToTimeStamp();
var runId = Guid.NewGuid().ToString();
var srcBeforMD5 = $"{runId}{feeKey.Value}expend{bsType}0{id}{order.MBLNO}{seconds}{feeKey.Value}";
var postObj = new
{
runId,
userId = feeUserId.Value,
module = "expend",//固定
bsType = $"{bsType}",
sendType = $"{sendType}",
timestamp = seconds,//秒级时间戳
md5 = srcBeforMD5.ToMd5(),// 加密字符串小写 RunId + UserId + Module + BsType + SendType+Timestamp+ Key
Data = new
{
BSNO = 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 = Convert.ToInt32(jobjApiRtn.GetValue("code").ToString());
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 = id;
fr.Type = typeStr;
fr.Amount = total;
await repoFeeRecord.InsertAsync(fr);
}
else
{
var errMsg = jobjApiRtnData.GetValue("message").ToString();
_logger.LogError($"扣费失败:{errMsg}");
DingTalkGroupHelper.SendDingTalkGroupMessage("bookingFeeNotify", "扣费失败提醒", errMsg);
}
}
_logger.LogInformation($"扣费处理完成");
}
}
}