sunpengfei
1 天以前 285404b0f7161ceca8621e61026682bbbb3f71aa
FlexJobApi.Core/Jobs/RefreshEnterpriseWalletTransactionStatusJob.cs
@@ -1,12 +1,14 @@
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;
@@ -16,26 +18,41 @@
{
    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();
                    .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
@@ -44,33 +61,80 @@
                            BizScene = entity.BizScene,
                            OutBizNo = entity.Code
                        });
                        if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg);
                        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
                            : response.Status == "FAIL"
                            ? EnumWalletTransactionStatus.Fail
                            : throw Oops.Oh(EnumErrorCodeType.s510, $"未识别的状态:{response.Status}");
                        await rep.UpdateAsync(entity);
                        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)
@@ -98,5 +162,17 @@
                }
            }
        }
        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);
            }
        }
    }
}