using Aop.Api.Domain;
|
using Furion;
|
using Furion.DatabaseAccessor;
|
using Furion.DistributedIDGenerator;
|
using Furion.FriendlyException;
|
using Furion.Schedule;
|
using Microsoft.EntityFrameworkCore;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Security.Cryptography.Xml;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
|
namespace FlexJobApi.Core.Jobs
|
{
|
public class RefreshEnterpriseWalletTransactionStatusJob(
|
IRepository<EnterpriseWalletTransaction> rep,
|
IRepository<UserWalletTransaction> repUserWalletTransaction,
|
IRepository<EnterpriseWallet> repEnterpriseWallet,
|
IRepository<UserWallet> repUserWallet,
|
AlipayUtils alipayUtils
|
) : IJob
|
{
|
private readonly IRepository<EnterpriseWalletTransaction> rep = rep;
|
private readonly IRepository<UserWalletTransaction> repUserWalletTransaction = repUserWalletTransaction;
|
private readonly IRepository<EnterpriseWallet> repEnterpriseWallet = repEnterpriseWallet;
|
private readonly IRepository<UserWallet> repUserWallet = repUserWallet;
|
private readonly AlipayUtils alipayUtils = alipayUtils;
|
|
[UnitOfWork(false)]
|
public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
|
{
|
var env = App.GetConfig<string>("Environment");
|
if (env != "Local")
|
{
|
var entities = await rep.AsQueryable()
|
.Where(it =>
|
it.TransactionStatus == EnumWalletTransactionStatus.WaitPay
|
|| it.TransactionStatus == EnumWalletTransactionStatus.Dealing)
|
.ToListAsync();
|
if (entities.IsNotNull())
|
{
|
var ids = entities.Select(it => it.Id).ToList();
|
var withdraws = await repUserWalletTransaction.AsQueryable()
|
.Where(it =>
|
it.EnterpriseWalletTransactionId.HasValue
|
&& ids.Contains(it.EnterpriseWalletTransactionId.Value))
|
.ToListAsync();
|
var userWalletIds = withdraws.DistinctSelect(it => it.WalletId).ToList();
|
var userWallets = await repUserWallet.AsQueryable()
|
.Where(it => userWalletIds.Contains(it.Id))
|
.ToListAsync();
|
foreach (var entity in entities)
|
{
|
var response = alipayUtils.FundTransCommonQuery(new Aop.Api.Domain.AlipayFundTransCommonQueryModel
|
{
|
ProductCode = entity.ProductCode,
|
BizScene = entity.BizScene,
|
OutBizNo = entity.Code
|
});
|
if (response.IsError)
|
{
|
entity.ErrorCode = response.ErrorCode;
|
entity.FailReason = response.FailReason;
|
}
|
else
|
{
|
entity.OrderId = response.OrderId;
|
entity.InflowSettleSerialNo = response.InflowSettleSerialNo;
|
entity.SettleSerialNo = response.SettleSerialNo;
|
entity.ReceiverOpenId = response.ReceiverOpenId;
|
entity.ReceiverUserId = response.ReceiverUserId;
|
entity.PayFundOrderId = response.PayFundOrderId;
|
entity.ArrivalTimeEnd = response.ArrivalTimeEnd.ToDateTime();
|
entity.OrderFee = response.OrderFee.ToDecimal();
|
entity.ErrorCode = response.ErrorCode;
|
entity.FailReason = response.FailReason;
|
entity.FailInstReason = response.FailInstReason;
|
entity.FailInstName = response.FailInstName;
|
entity.FailInstErrorCode = response.FailInstErrorCode;
|
entity.SubStatus = response.SubStatus;
|
entity.TransDate = response.PayDate.ToDateTime();
|
entity.Status = response.Status;
|
entity.TransactionStatus = response.Status == "SUCCESS"
|
? EnumWalletTransactionStatus.Success
|
: response.Status == "DEALING"
|
? EnumWalletTransactionStatus.Dealing
|
: response.Status == "REFUND"
|
? EnumWalletTransactionStatus.Refund
|
: EnumWalletTransactionStatus.Fail;
|
}
|
await rep.UpdateNowAsync(entity);
|
|
var withdraw = withdraws.FirstOrDefault(it => it.EnterpriseWalletTransactionId == entity.Id);
|
if (withdraw != null)
|
{
|
var userWallet = userWallets.FirstOrDefault(it => it.Id == withdraw.WalletId);
|
if (userWallet != null)
|
{
|
withdraw.ErrorCode = entity.ErrorCode;
|
withdraw.FailReason = entity.FailReason;
|
withdraw.EnterpriseWalletTransactionId = entity.Id;
|
withdraw.TransactionStatus = entity.TransactionStatus;
|
withdraw.TransDate = entity.TransDate;
|
withdraw.ArrivalTimeEnd = entity.ArrivalTimeEnd;
|
withdraw.ServiceFee = entity.OrderFee ?? 0;
|
if (withdraw.TransactionStatus == EnumWalletTransactionStatus.Success)
|
{
|
withdraw.ActualAmount = withdraw.Amount;
|
}
|
else
|
{
|
withdraw.ActualAmount = 0;
|
|
var order = new UserWalletTransaction();
|
order.WalletId = withdraw.WalletId;
|
order.Type = EnumUserWalletTransactionType.Income;
|
order.OperatorUserId = withdraw.OperatorUserId;
|
order.OperatorTime = withdraw.OperatorTime;
|
order.Title = $"收入-提现失败退款";
|
order.Amount = withdraw.Amount;
|
order.ActualAmount = order.Amount;
|
order.Balance = userWallet.Balance;
|
order.AfterBalance = userWallet.Balance + order.Amount;
|
order.TransDate = DateTime.Now;
|
order.TransactionStatus = EnumWalletTransactionStatus.Success;
|
await SetCode(order);
|
await repUserWalletTransaction.InsertNowAsync(order);
|
|
userWallet.Balance = order.AfterBalance;
|
await repUserWallet.UpdateNowAsync(userWallet);
|
}
|
}
|
}
|
}
|
var walletIds = entities
|
.Where(it => it.TransactionStatus == EnumWalletTransactionStatus.Success)
|
.Select(it => it.WalletId)
|
.Distinct()
|
.ToList();
|
if (walletIds.IsNotNull())
|
{
|
var wallets = await repEnterpriseWallet.AsQueryable()
|
.Where(it => walletIds.Contains(it.Id))
|
.ToListAsync();
|
foreach (var wallet in wallets)
|
{
|
var response = alipayUtils.FundAccountbookQuery(new AlipayFundAccountbookQueryModel
|
{
|
AccountBookId = wallet.AccountBookId,
|
SceneCode = "SATF_FUND_BOOK",
|
MerchantUserId = wallet.Code,
|
});
|
if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg);
|
wallet.Balance = response.AvailableAmount.ToDecimal() ?? 0;
|
await repEnterpriseWallet.UpdateAsync(wallet);
|
}
|
}
|
}
|
}
|
}
|
|
private async Task SetCode(UserWalletTransaction entity)
|
{
|
entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}";
|
var exist = await repUserWalletTransaction.AsQueryable().AsNoTracking()
|
.AnyAsync(it => it.Code == entity.Code);
|
if (exist)
|
{
|
await SetCode(entity);
|
}
|
}
|
|
}
|
}
|