| ApiTools.Application/ApiTools.Application.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ApiTools.Application/ChannelWallets/Queries/ChannelWalletQueryHandler.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ApiTools.Core/ApiTools.Core.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ApiTools.Core/Jobs/RefreshChannelWalletTransactionStatusJob.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ApiTools.Core/Models/ChannelWallets/Queries/GetChannelWalletTransactionsQuery.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ApiTools.Application/ApiTools.Application.xml
@@ -191,6 +191,14 @@ <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.ChannelWalletQueryHandler.Handle(ApiTools.Core.GetChannelWalletTransactionsQuery,System.Threading.CancellationToken)"> <summary> 查询渠道钱包交易详情 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.SendSmsCommandHandler.Handle(ApiTools.Core.SendSmsCommand,System.Threading.CancellationToken)"> <summary> 发送短信 ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
@@ -90,37 +90,76 @@ await channelWalletService.GetEnterpriseWalletBalance(wallet); if (request.Amount > wallet.Balance) throw Oops.Oh(EnumErrorCodeType.s404, "余额不足"); var checkExist = await channelWalletTransactionRepository.GetQueryable() .AnyAsync(it => it.WalletId == wallet.Id && it.OutCode == request.OutCode); if (checkExist) throw Oops.Oh(EnumErrorCodeType.s405, "交易单号"); var transaction = new ChannelWalletTransaction(); transaction.Type = EnumWalletTransactionType.Transfer; transaction.WalletId = wallet.Id; transaction.OutCode = request.OutCode; transaction.ConcurrencyLock = $"{logier.ChannelId}:{transaction.OutCode}"; transaction.Amount = request.Amount; transaction.Remark = request.Remark; transaction.TransactionStatus = EnumWalletTransactionStatus.WaitSubmit; transaction.Balance = wallet.Balance; transaction.AfterBalance = wallet.Balance - transaction.Amount; transaction.OutOperatorId = request.OutOperatorId; transaction.OperatorTime = request.OperatorTime; transaction.PayerName = wallet.Name; transaction.PayerAccount = wallet.Identity; transaction.PayerBank = wallet.Bank; transaction.PayerBankBranch = wallet.BankBranch; transaction.OutReceiveId = request.OutReceiveId; transaction.ReceiveBank = request.ReceiveBank; transaction.ReceiveBankBranch = request.ReceiveBankBranch; transaction.ReceiveName = request.ReceiveName; transaction.ReceiveIdentity = request.ReceiveIdentity; transaction.ReceiveAccount = request.ReceiveAccount; transaction.Currency = request.Currency; transaction.Purpose = request.Purpose; transaction.Remark = request.Remark; await channelWalletTransactionRepository.SetCode(transaction); await channelWalletTransactionRepository.InsertNowAsync(transaction); var transaction = await channelWalletTransactionRepository.GetQueryable() .Where(it => it.WalletId == wallet.Id && it.OutCode == request.OutCode) .FirstOrDefaultAsync(); if (transaction == null) { transaction = new ChannelWalletTransaction(); transaction.Type = EnumWalletTransactionType.Transfer; transaction.WalletId = wallet.Id; transaction.OutCode = request.OutCode; transaction.ConcurrencyLock = $"{logier.ChannelId}:{transaction.OutCode}"; transaction.TransactionStatus = EnumWalletTransactionStatus.WaitSubmit; transaction.Amount = request.Amount; transaction.Balance = wallet.Balance; transaction.AfterBalance = wallet.Balance - transaction.Amount; transaction.OutOperatorId = request.OutOperatorId; transaction.OperatorTime = request.OperatorTime; transaction.PayerName = wallet.Name; transaction.PayerAccount = wallet.Identity; transaction.PayerBank = wallet.Bank; transaction.PayerBankBranch = wallet.BankBranch; transaction.OutReceiveId = request.OutReceiveId; transaction.ReceiveBank = request.ReceiveBank; transaction.ReceiveBankBranch = request.ReceiveBankBranch; transaction.ReceiveName = request.ReceiveName; transaction.ReceiveIdentity = request.ReceiveIdentity; transaction.ReceiveAccount = request.ReceiveAccount; transaction.Currency = request.Currency; transaction.Purpose = request.Purpose; transaction.Remark = request.Remark; await channelWalletTransactionRepository.SetCode(transaction); await channelWalletTransactionRepository.InsertNowAsync(transaction); } else { switch (transaction.TransactionStatus) { case EnumWalletTransactionStatus.WaitSubmit: throw Oops.Oh(EnumErrorCodeType.s510, "已存在正在处理的转账,请勿重复操作"); case EnumWalletTransactionStatus.WaitPay: case EnumWalletTransactionStatus.Dealing: throw Oops.Oh(EnumErrorCodeType.s510, "转账正在进行中,请勿重复操作"); case EnumWalletTransactionStatus.Success: throw Oops.Oh(EnumErrorCodeType.s510, "已转账,请勿重复操作"); case EnumWalletTransactionStatus.Refund: case EnumWalletTransactionStatus.Fail: transaction.TransactionStatus = EnumWalletTransactionStatus.WaitSubmit; transaction.Amount = request.Amount; transaction.Balance = wallet.Balance; transaction.AfterBalance = wallet.Balance - transaction.Amount; transaction.OutOperatorId = request.OutOperatorId; transaction.OperatorTime = request.OperatorTime; transaction.PayerName = wallet.Name; transaction.PayerAccount = wallet.Identity; transaction.PayerBank = wallet.Bank; transaction.PayerBankBranch = wallet.BankBranch; transaction.OutReceiveId = request.OutReceiveId; transaction.ReceiveBank = request.ReceiveBank; transaction.ReceiveBankBranch = request.ReceiveBankBranch; transaction.ReceiveName = request.ReceiveName; transaction.ReceiveIdentity = request.ReceiveIdentity; transaction.ReceiveAccount = request.ReceiveAccount; transaction.Currency = request.Currency; transaction.Purpose = request.Purpose; transaction.Remark = request.Remark; await channelWalletTransactionRepository.UpdateNowAsync(transaction); break; default: break; } } await channelWalletService.Transfer(wallet, transaction); return new SubmitChannelWalletTransferCommandResult { ApiTools.Application/ChannelWallets/Queries/ChannelWalletQueryHandler.cs
@@ -18,7 +18,8 @@ ChannelWalletTransactionRepository channelWalletTransactionRepository ) : IRequestHandler<GetChannelPingAnPayWalletQuery, GetChannelPingAnPayWalletQueryResult>, IRequestHandler<GetChannelWalletTransactionQuery, GetChannelWalletTransactionQueryResult> IRequestHandler<GetChannelWalletTransactionQuery, GetChannelWalletTransactionQueryResult>, IRequestHandler<GetChannelWalletTransactionsQuery, GetChannelWalletTransactionsQueryResult> { private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository; private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository; @@ -51,5 +52,28 @@ .FirstOrDefaultAsync(); } /// <summary> /// 查询渠道钱包交易详情 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<GetChannelWalletTransactionsQueryResult> Handle(GetChannelWalletTransactionsQuery request, CancellationToken cancellationToken) { var list = new GetChannelWalletTransactionsQueryResult(); list.Items = await channelWalletTransactionRepository.GetQueryable() .Where(it => request.OutCodes.Contains(it.OutCode)) .ProjectToType<GetChannelWalletTransactionsQueryResultItem>() .ToListAsync(); foreach (var item in list.Items) { if (item.EreceiptStatus == EnumWalletTransactionEreceiptStatus.SUCCESS && item.EreceiptDownloadOssUrl.IsNotNull()) { item.EreceiptDownloadOssFullUrl = AliyunOSSUtils.GetUrl(item.EreceiptDownloadOssUrl); } } return list; } } } ApiTools.Core/ApiTools.Core.xml
@@ -2633,6 +2633,201 @@ 状态 </summary> </member> <member name="T:ApiTools.Core.GetChannelWalletTransactionsQuery"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQuery.OutCodes"> <summary> 外部订单号 </summary> </member> <member name="T:ApiTools.Core.GetChannelWalletTransactionsQueryResult"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResult.Items"> <summary> 项 </summary> </member> <member name="T:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Id"> <summary> 交易Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Type"> <summary> 类型 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Code"> <summary> 订单号 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.OutCode"> <summary> 外部订单号 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ConcurrencyLock"> <summary> 并发锁 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Amount"> <summary> 金额 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Balance"> <summary> 余额 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.AfterBalance"> <summary> 收支后余额 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.OutOperatorId"> <summary> 外部操作人Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.OperatorTime"> <summary> 操作时间 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.PayerAccount"> <summary> 付款人账户 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.PayerName"> <summary> 付款人名称 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.PayerBank"> <summary> 付款人开户行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.PayerBankBranch"> <summary> 付款人支行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.OutReceiveId"> <summary> 外部收款人Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ReceiveName"> <summary> 收款人姓名 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ReceiveIdentity"> <summary> 收款人身份证号 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ReceiveBank"> <summary> 收款人开户行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ReceiveBankBranch"> <summary> 收款人支行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Currency"> <summary> 币种 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Purpose"> <summary> 用途 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.Remark"> <summary> 备注 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.ErrorCode"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.FailReason"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.TransDate"> <summary> 订单支付时间 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.OrderFee"> <summary> 预计收费金额(元),转账到银行卡专用 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.EreceiptFileId"> <summary> 电子收据Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.EreceiptDownloadUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.EreceiptDownloadOssUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.EreceiptDownloadOssFullUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.EreceiptStatus"> <summary> 电子收据状态 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.EreceiptErrorMessage"> <summary> 电子收据错误信息 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionsQueryResultItem.TransactionStatus"> <summary> 状态 </summary> </member> <member name="T:ApiTools.Core.CheckHealthQuery"> <summary> 健康校验 ApiTools.Core/Jobs/RefreshChannelWalletTransactionStatusJob.cs
@@ -29,15 +29,15 @@ public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { var env = App.GetConfig<string>("Environment"); if (env != "Local") { //var env = App.GetConfig<string>("Environment"); //if (env != "Local") //{ var transactions = await channelWalletTransactionRepository.GetQueryable(false) .Where(it => it.TransactionStatus == EnumWalletTransactionStatus.WaitPay || it.TransactionStatus == EnumWalletTransactionStatus.Dealing) .ToListAsync(); var walletIds = transactions.DistinctSelect(it => it.WalletId); var walletIds = transactions.Select(it => it.WalletId).Distinct().ToList(); var wallets = await channelWalletRepository.GetQueryable(false) .Where(it => walletIds.Contains(it.Id)) .ToListAsync(); @@ -52,7 +52,7 @@ await channelWalletService.DownloadEreceiptUrl(wallet, transaction); } } } //} } } } ApiTools.Core/Models/ChannelWallets/Queries/GetChannelWalletTransactionsQuery.cs
New file @@ -0,0 +1,208 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 查询渠道钱包交易详情 /// </summary> [Resource([EnumResourceController.UserServerChannelWallet], Method = EnumResourceMethod.Post)] public class GetChannelWalletTransactionsQuery : IRequest<GetChannelWalletTransactionsQueryResult> { /// <summary> /// 外部订单号 /// </summary> public List<string> OutCodes { get; set; } = []; } /// <summary> /// 查询渠道钱包交易详情 /// </summary> public class GetChannelWalletTransactionsQueryResult { /// <summary> /// 项 /// </summary> public List<GetChannelWalletTransactionsQueryResultItem> Items { get; set; } = []; } /// <summary> /// 查询渠道钱包交易详情 /// </summary> public class GetChannelWalletTransactionsQueryResultItem { /// <summary> /// 交易Id /// </summary> public Guid Id { get; set; } /// <summary> /// 类型 /// </summary> public EnumWalletTransactionType Type { get; set; } /// <summary> /// 订单号 /// </summary> public string Code { get; set; } /// <summary> /// 外部订单号 /// </summary> public string OutCode { get; set; } /// <summary> /// 并发锁 /// </summary> public string ConcurrencyLock { get; set; } /// <summary> /// 金额 /// </summary> public decimal Amount { get; set; } /// <summary> /// 余额 /// </summary> public decimal Balance { get; set; } /// <summary> /// 收支后余额 /// </summary> public decimal AfterBalance { get; set; } /// <summary> /// 外部操作人Id /// </summary> public string OutOperatorId { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime? OperatorTime { get; set; } /// <summary> /// 付款人账户 /// </summary> public string PayerAccount { get; set; } /// <summary> /// 付款人名称 /// </summary> public string PayerName { get; set; } /// <summary> /// 付款人开户行 /// </summary> public string PayerBank { get; set; } /// <summary> /// 付款人支行 /// </summary> public string PayerBankBranch { get; set; } /// <summary> /// 外部收款人Id /// </summary> public string OutReceiveId { get; set; } /// <summary> /// 收款人姓名 /// </summary> public string ReceiveName { get; set; } /// <summary> /// 收款人身份证号 /// </summary> public string ReceiveIdentity { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 收款人开户行 /// </summary> public string ReceiveBank { get; set; } /// <summary> /// 收款人支行 /// </summary> public string ReceiveBankBranch { get; set; } /// <summary> /// 币种 /// </summary> public string Currency { get; set; } /// <summary> /// 用途 /// </summary> public string Purpose { get; set; } /// <summary> /// 备注 /// </summary> public string Remark { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 /// </summary> public string ErrorCode { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 /// </summary> public string FailReason { get; set; } /// <summary> /// 订单支付时间 /// </summary> public DateTime? TransDate { get; set; } /// <summary> /// 预计收费金额(元),转账到银行卡专用 /// </summary> public decimal? OrderFee { get; set; } /// <summary> /// 电子收据Id /// </summary> public string EreceiptFileId { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadUrl { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadOssUrl { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadOssFullUrl { get; set; } /// <summary> /// 电子收据状态 /// </summary> public EnumWalletTransactionEreceiptStatus? EreceiptStatus { get; set; } /// <summary> /// 电子收据错误信息 /// </summary> public string EreceiptErrorMessage { get; set; } /// <summary> /// 状态 /// </summary> public EnumWalletTransactionStatus TransactionStatus { get; set; } } }