From 7b47c91bcf89d667a5c99cfafe0d899280f7fbe3 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期三, 19 十一月 2025 11:22:27 +0800
Subject: [PATCH] feat:平安转账开发

---
 ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs |  135 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 135 insertions(+), 0 deletions(-)

diff --git a/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs b/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
new file mode 100644
index 0000000..0fd2503
--- /dev/null
+++ b/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
@@ -0,0 +1,135 @@
+锘縰sing Aop.Api.Domain;
+using ApiTools.Core;
+using Consul;
+using Furion.FriendlyException;
+using Mapster;
+using Medallion.Threading;
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ApiTools.Application
+{
+    public class ChannelWalletCommandHandler(
+            IDistributedLockProvider distributedLockProvider,
+            ChannelWalletRepository channelWalletRepository,
+            ChannelWalletTransactionRepository channelWalletTransactionRepository,
+            ChannelWalletService channelWalletService
+        ) :
+        IRequestHandler<SaveChannelPingAnPayWalletCommand, SaveChannelPingAnPayWalletCommandResult>,
+        IRequestHandler<SubmitChannelWalletTransferCommand, SubmitChannelWalletTransferCommandResult>
+    {
+        private readonly IDistributedLockProvider distributedLockProvider = distributedLockProvider;
+        private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository;
+        private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository;
+        private readonly ChannelWalletService channelWalletService = channelWalletService;
+
+        /// <summary>
+        /// 淇濆瓨娓犻亾骞冲畨閾惰閽卞寘
+        /// </summary>
+        /// <param name="request"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task<SaveChannelPingAnPayWalletCommandResult> Handle(SaveChannelPingAnPayWalletCommand request, CancellationToken cancellationToken)
+        {
+            var logier = JwtUtils.GetCurrentLogier();
+            var wallet = await channelWalletRepository.GetQueryable(false)
+                .Where(it => it.ChannelId == logier.ChannelId && it.OutWalletId == request.OutWalletId)
+                .FirstOrDefaultAsync();
+            if (wallet == null)
+            {
+                wallet = new ChannelWallet();
+                wallet.ChannelId = logier.ChannelId;
+                wallet.Access = EnumWalletAccess.PingAnPay;
+                wallet.Bank = "骞冲畨閾惰";
+                wallet.SignStatus = EnumWalletSignStatus.Apply;
+                request.Adapt(wallet);
+                await channelWalletRepository.SetCode(wallet);
+                await channelWalletRepository.InsertNowAsync(wallet);
+            }
+            else
+            {
+                wallet.SignStatus = EnumWalletSignStatus.Apply;
+                request.Adapt(wallet);
+                await channelWalletRepository.UpdateNowAsync(wallet);
+            }
+            await channelWalletService.GetEnterpriseWalletBalance(wallet);
+            return new SaveChannelPingAnPayWalletCommandResult
+            {
+                Id = wallet.Id,
+                Balance = wallet.Balance,
+            };
+        }
+
+        /// <summary>
+        /// 鎻愪氦娓犻亾閽卞寘杞处
+        /// </summary>
+        /// <param name="request"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task<SubmitChannelWalletTransferCommandResult> Handle(SubmitChannelWalletTransferCommand request, CancellationToken cancellationToken)
+        {
+            var logier = JwtUtils.GetCurrentLogier();
+
+            await using var handle = await distributedLockProvider.TryAcquireAsync(
+                channelWalletService.GetLockKey(logier.ChannelId.Value, request.OutWalletId),
+                TimeSpan.FromMinutes(30));
+            if (handle == null) throw Oops.Oh(EnumErrorCodeType.s429);
+
+            var wallet = await channelWalletRepository.GetQueryable(false)
+                .Where(it => it.ChannelId == logier.ChannelId && it.OutWalletId == request.OutWalletId)
+                .FirstOrDefaultAsync();
+
+            if (wallet == null) throw Oops.Oh(EnumErrorCodeType.s404, "鏈紑閫氶挶鍖�");
+            if (wallet.SignStatus != EnumWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s404, "閽卞寘鏈绾�");
+            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);
+            await channelWalletService.Transfer(wallet, transaction);
+            return new SubmitChannelWalletTransferCommandResult
+            {
+                Id = transaction.Id,
+                Code = transaction.Code,
+                TransactionStatus = transaction.TransactionStatus,
+                ErrorCode = transaction.ErrorCode,
+                FailReason = transaction.FailReason,
+            };
+        }
+    }
+}

--
Gitblit v1.9.1