From c33b59a63a99a4598d6d6bc56750efd4f7ad550d Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期二, 09 九月 2025 15:19:42 +0800
Subject: [PATCH] feat:开发

---
 FlexJobApi.Core/Jobs/CompleteTaskSettlementT1Job.cs |  386 ++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 297 insertions(+), 89 deletions(-)

diff --git a/FlexJobApi.Core/Jobs/CompleteTaskSettlementT1Job.cs b/FlexJobApi.Core/Jobs/CompleteTaskSettlementT1Job.cs
index 032363c..2c9c5a5 100644
--- a/FlexJobApi.Core/Jobs/CompleteTaskSettlementT1Job.cs
+++ b/FlexJobApi.Core/Jobs/CompleteTaskSettlementT1Job.cs
@@ -1,10 +1,12 @@
 锘縰sing Aop.Api.Domain;
+using Azure;
 using Furion;
 using Furion.DatabaseAccessor;
 using Furion.DistributedIDGenerator;
 using Furion.FriendlyException;
 using Furion.Schedule;
 using Microsoft.EntityFrameworkCore;
+using StackExchange.Redis;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -23,12 +25,16 @@
             IRepository<TaskInfoUser> repTaskInfoUser,
             IRepository<EnterpriseWallet> repEnterpriseWallet,
             IRepository<EnterpriseWalletTransaction> repEnterpriseWalletTransaction,
+            IRepository<UserWallet> repUserWallet,
+            IRepository<UserWalletTransaction> repUserWalletTransaction,
             AlipayUtils alipayUtils
         ) : IJob
     {
         private readonly IRepository<TaskInfo> rep = rep;
         private readonly IRepository<TaskInfoUser> repTaskInfoUser = repTaskInfoUser;
         private readonly IRepository<EnterpriseWallet> repEnterpriseWallet = repEnterpriseWallet;
+        private readonly IRepository<UserWallet> repUserWallet = repUserWallet;
+        private readonly IRepository<UserWalletTransaction> repUserWalletTransaction = repUserWalletTransaction;
         private readonly AlipayUtils alipayUtils = alipayUtils;
 
         [UnitOfWork(false)]
@@ -37,39 +43,19 @@
             var env = App.GetConfig<string>("Environment");
             if (env != "Local")
             {
-                var now = DateTime.Now;
-                var q = rep.AsQueryable()
-                    .Where(it => it.SettlementStatus == EnumTaskSettlementStatus.InProcess);
-                var minTime = env == "Test"
-                    ? now.AddMinutes(-5)
-                    : now.AddDays(-1);
-                q = q.Where(it => it.SettlementStartTime.HasValue && it.SettlementStartTime < minTime);
-                var tasks = await q.ToListAsync();
+                var tasks = await GetTasks(env);
                 var enterpriseIds = tasks.DistinctSelect(it => it.EnterpriseId);
                 var taskIds = tasks.DistinctSelect(it => it.Id);
-                var taskUsers = await repTaskInfoUser
-                    .Where(it => taskIds.Contains(it.TaskInfoId) && it.SettlementStatus == EnumTaskSettlementStatus.InProcess)
-                    .ToListAsync();
-                var wallets = await repEnterpriseWallet.AsQueryable()
-                    .Where(it => enterpriseIds.Contains(it.EnterpriseId) && it.Access == EnumEnterpriseWalletAccess.Alipay)
-                    .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.UpdateNowAsync(wallet);
-                }
+                var taskUsers = await GetTaskUsers(taskIds);
+                var userIds = taskUsers.DistinctSelect(it => it.EnterpriseEmployee.UserId.Value);
+                var userWallets = await GetUserWallets(userIds);
+                var enterpriseWallets = await GetEnterpriseWallets(enterpriseIds);
                 if (tasks.IsNotNull())
                 {
                     foreach (var task in tasks)
                     {
-                        var wallet = wallets.FirstOrDefault(it => it.EnterpriseId == task.EnterpriseId);
+                        var enterpriseWallet = enterpriseWallets.FirstOrDefault(it => it.EnterpriseId == task.EnterpriseId);
+
                         task.SettlementStatus = EnumTaskSettlementStatus.Completed;
                         task.SettlementTime = DateTime.Now;
                         await rep.UpdateNowAsync(task);
@@ -81,75 +67,286 @@
                             user.SettlementTime = DateTime.Now;
                             await repTaskInfoUser.UpdateNowAsync(user);
 
-                            var order = new EnterpriseWalletTransaction();
-                            order.Type = EnumEnterpriseWalletTransactionType.Recharge;
-                            order.WalletId = wallet.Id;
-                            order.Amount = user.ActualSettlementAmount ?? 0;
-                            order.Remark = user.SettlementRemark;
-                            order.ProductCode = "SINGLE_TRANSFER_NO_PWD";
-                            order.BizScene = "ENTRUST_TRANSFER";
-                            order.TransactionStatus = EnumEnterpriseWalletTransactionStatus.WaitSubmit;
-                            order.Balance = wallet.Balance;
-                            await SetCode(order);
-                            await repEnterpriseWalletTransaction.InsertNowAsync(order);
+                            var userWallet = await AddUserWalletTransactionIncome(userWallets, task, user);
 
-                            var response = alipayUtils.FundTransUniTransfer(new AlipayFundTransUniTransferModel
-                            {
-                                OutBizNo = order.Code,
-                                TransAmount = order.Amount.ToString(),
-                                ProductCode = order.ProductCode,
-                                BizScene = order.BizScene,
-                                PayeeInfo = new Participant
-                                {
-                                    IdentityType = "ALIPAY_LOGON_ID",
-                                    Identity = user.ReceiveAccount,
-                                    Name = user.ReceiveName,
-                                },
-                                PayerInfo = new Participant
-                                {
-                                    IdentityType = "ACCOUNT_BOOK_ID",
-                                    Identity = wallet.AccountBookId,
-                                    ExtInfo = new
-                                    {
-                                        agreement_no = wallet.AgreementNo,
-                                    }.ToJson(),
-                                },
-                                OrderTitle = order.Remark,
-                                Remark = order.Remark,
-                                BusinessParams = new
-                                {
-                                    withdraw_timeliness = "T0"
-                                }.ToJson()
-                            }, "/api/user/enterpriseWallet/alipayFundTransOrderChangedNotify");
-                            if (response.IsError)
-                            {
-                                order.ErrorCode = response.Code;
-                                order.FailReason = response.SubMsg ?? response.Msg;
-                            }
-                            else
-                            {
-                                order.OrderId = response.OrderId;
-                                order.PayFundOrderId = response.PayFundOrderId;
-                                order.SettleSerialNo = response.SettleSerialNo;
-                                order.TransDate = response.TransDate.ToDateTime();
-                                order.Link = response.Link;
-                                order.Status = response.Status;
-                                order.SubStatus = response.SubStatus;
-                                order.TransactionStatus = response.Status == "SUCCESS"
-                                    ? EnumEnterpriseWalletTransactionStatus.Success
-                                    : response.Status == "DEALING"
-                                    ? EnumEnterpriseWalletTransactionStatus.Dealing
-                                    : response.Status == "REFUND"
-                                    ? EnumEnterpriseWalletTransactionStatus.Refund
-                                    : EnumEnterpriseWalletTransactionStatus.Fail;
-                                await repEnterpriseWalletTransaction.UpdateNowAsync(order);
-                            }
+                            var withdraw = await AddUserWalletTransactionWithdraw(userWallet, task, user);
+
+                            var transfer = await AddEnterpriseWalletTransactionTransfer(enterpriseWallet, task, user);
+
+                            await UpdateUserWalletTransactionWithdraw(userWallet, withdraw, transfer);
                         }
                     }
                 }
             }
         }
 
+        /// <summary>
+        /// 鏇存柊鐢ㄦ埛閽卞寘鎻愮幇璁板綍
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <param name="withdraw"></param>
+        /// <param name="transfer"></param>
+        /// <returns></returns>
+        private async Task UpdateUserWalletTransactionWithdraw(UserWallet wallet, UserWalletTransaction withdraw, EnterpriseWalletTransaction transfer)
+        {
+            withdraw.EnterpriseWalletTransactionId = transfer.Id;
+            withdraw.TransactionStatus = transfer.TransactionStatus;
+            withdraw.TransDate = transfer.TransDate;
+            if (withdraw.TransactionStatus == EnumWalletTransactionStatus.Success)
+            {
+                withdraw.ActualAmount = withdraw.Amount;
+            }
+            else
+            {
+                withdraw.ActualAmount = 0;
+
+                var order = new UserWalletTransaction();
+                order.WalletId = wallet.Id;
+                order.Type = EnumUserWalletTransactionType.Income;
+                order.OperatorUserId = withdraw.OperatorUserId;
+                order.OperatorTime = withdraw.OperatorTime;
+                order.Title = $"鏀跺叆-鎻愮幇澶辫触閫�娆�";
+                order.Amount = withdraw.Amount;
+                order.ActualAmount = order.Amount;
+                order.Balance = wallet.Balance;
+                order.AfterBalance = wallet.Balance + order.Amount;
+                order.TransDate = DateTime.Now;
+                order.TransactionStatus = EnumWalletTransactionStatus.Success;
+                await SetCode(order);
+                await repUserWalletTransaction.InsertNowAsync(order);
+
+                wallet.Balance = order.AfterBalance;
+                await repUserWallet.UpdateNowAsync(wallet);
+            }
+        }
+
+        /// <summary>
+        /// 娣诲姞鐢ㄦ埛閽卞寘鎻愮幇璁板綍
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <param name="task"></param>
+        /// <param name="user"></param>
+        /// <returns></returns>
+        private async Task<UserWalletTransaction> AddUserWalletTransactionWithdraw(UserWallet wallet, TaskInfo task, TaskInfoUser user)
+        {
+            wallet.Balance -= user.ActualSettlementAmount ?? 0;
+            await repUserWallet.UpdateNowAsync(wallet);
+
+            var order = new UserWalletTransaction();
+            order.WalletId = wallet.Id;
+            order.Type = EnumUserWalletTransactionType.Withdraw;
+            order.OperatorUserId = task.SettlementOperatorUserId;
+            order.OperatorTime = task.SettlementStartTime;
+            order.Title = $"鎻愮幇-鏀粯瀹濇彁鐜�";
+            order.Amount = user.ActualSettlementAmount ?? 0;
+            order.Balance = wallet.Balance;
+            order.AfterBalance = wallet.Balance - order.Amount;
+            order.ReceiveName = user.ReceiveName;
+            order.ReceiveAccount = user.ReceiveAccount;
+            order.TransDate = DateTime.Now;
+            order.TransactionStatus = EnumWalletTransactionStatus.Dealing;
+            await SetCode(order);
+            await repUserWalletTransaction.InsertNowAsync(order);
+            return order;
+        }
+
+        /// <summary>
+        /// 娣诲姞鐢ㄦ埛閽卞寘鏀跺叆璁板綍
+        /// </summary>
+        /// <param name="wallets"></param>
+        /// <param name="task"></param>
+        /// <param name="user"></param>
+        /// <returns></returns>
+        private async Task<UserWallet> AddUserWalletTransactionIncome(List<UserWallet> wallets, TaskInfo task, TaskInfoUser user)
+        {
+            var wallet = wallets.FirstOrDefault(it => it.UserId == user.EnterpriseEmployee.UserId);
+            if (wallet == null)
+            {
+                wallet = new UserWallet();
+                wallet.UserId = user.EnterpriseEmployee.UserId.Value;
+                await repUserWallet.InsertNowAsync(wallet);
+            }
+            var order = new UserWalletTransaction();
+            order.WalletId = wallet.Id;
+            order.Type = EnumUserWalletTransactionType.Income;
+            order.TaskUserId = user.Id;
+            order.EnterpriseName = task.Enterprise.EnterpriseName;
+            order.SettlementTime = user.SettlementTime;
+            order.SettlementAmount = user.SettlementAmount;
+            order.OperatorUserId = task.SettlementOperatorUserId;
+            order.OperatorTime = task.SettlementStartTime;
+            order.Title = $"鏀跺叆-{order.EnterpriseName}";
+            order.Amount = user.ActualSettlementAmount ?? 0;
+            order.ActualAmount = order.Amount;
+            order.Balance = wallet.Balance;
+            order.AfterBalance = wallet.Balance + order.Amount;
+            order.TransDate = DateTime.Now;
+            order.TransactionStatus = EnumWalletTransactionStatus.Success;
+            await SetCode(order);
+            await repUserWalletTransaction.InsertNowAsync(order);
+
+            wallet.Balance = order.AfterBalance;
+            await repUserWallet.UpdateNowAsync(wallet);
+
+            return wallet;
+        }
+
+        /// <summary>
+        /// 娣诲姞浼佷笟閽卞寘杞处璁板綍
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <param name="task"></param>
+        /// <param name="user"></param>
+        /// <returns></returns>
+        private async Task<EnterpriseWalletTransaction> AddEnterpriseWalletTransactionTransfer(EnterpriseWallet wallet, TaskInfo task, TaskInfoUser user)
+        {
+            var order = new EnterpriseWalletTransaction();
+            order.Type = EnumEnterpriseWalletTransactionType.Transfer;
+            order.WalletId = wallet.Id;
+            order.TaskUserId = user.Id;
+            order.Amount = user.ActualSettlementAmount ?? 0;
+            order.Remark = user.SettlementRemark;
+            order.ProductCode = "SINGLE_TRANSFER_NO_PWD";
+            order.BizScene = "ENTRUST_TRANSFER";
+            order.TransactionStatus = EnumWalletTransactionStatus.WaitSubmit;
+            order.Balance = wallet.Balance;
+            order.AfterBalance = wallet.Balance - order.Amount;
+            order.OperatorUserId = task.SettlementOperatorUserId;
+            order.OperatorTime = task.SettlementStartTime;
+            order.ReceiveUserId = user.EnterpriseEmployee.UserId;
+            order.ReceiveName = user.ReceiveName;
+            order.ReceiveAccount = user.ReceiveAccount;
+            await SetCode(order);
+            await repEnterpriseWalletTransaction.InsertNowAsync(order);
+
+            var response = alipayUtils.FundTransUniTransfer(new AlipayFundTransUniTransferModel
+            {
+                OutBizNo = order.Code,
+                TransAmount = order.Amount.ToString(),
+                ProductCode = order.ProductCode,
+                BizScene = order.BizScene,
+                PayeeInfo = new Participant
+                {
+                    IdentityType = "ALIPAY_LOGON_ID",
+                    Identity = order.ReceiveAccount,
+                    Name = order.ReceiveName,
+                },
+                PayerInfo = new Participant
+                {
+                    IdentityType = "ACCOUNT_BOOK_ID",
+                    Identity = wallet.AccountBookId,
+                    ExtInfo = new
+                    {
+                        agreement_no = wallet.AgreementNo,
+                    }.ToJson(),
+                },
+                OrderTitle = order.Remark,
+                Remark = order.Remark,
+                BusinessParams = new
+                {
+                    withdraw_timeliness = "T0"
+                }.ToJson()
+            }, "/api/user/enterpriseWallet/alipayFundTransOrderChangedNotify");
+            if (response.IsError)
+            {
+                order.ErrorCode = response.Code;
+                order.FailReason = response.SubMsg ?? response.Msg;
+                await repEnterpriseWalletTransaction.UpdateNowAsync(order);
+            }
+            else
+            {
+                order.OrderId = response.OrderId;
+                order.PayFundOrderId = response.PayFundOrderId;
+                order.SettleSerialNo = response.SettleSerialNo;
+                order.TransDate = response.TransDate.ToDateTime();
+                order.Link = response.Link;
+                order.Status = response.Status;
+                order.SubStatus = response.SubStatus;
+                order.TransactionStatus = response.Status == "SUCCESS"
+                    ? EnumWalletTransactionStatus.Success
+                    : response.Status == "DEALING"
+                    ? EnumWalletTransactionStatus.Dealing
+                    : response.Status == "REFUND"
+                    ? EnumWalletTransactionStatus.Refund
+                    : EnumWalletTransactionStatus.Fail;
+                await repEnterpriseWalletTransaction.UpdateNowAsync(order);
+            }
+            return order;
+        }
+
+        /// <summary>
+        /// 鏌ヨ鐢ㄦ埛閽卞寘
+        /// </summary>
+        /// <param name="userIds"></param>
+        /// <returns></returns>
+        private async Task<List<UserWallet>> GetUserWallets(List<Guid> userIds)
+        {
+            var wallets = await repUserWallet.AsQueryable().AsNoTracking()
+                .Where(it => userIds.Contains(it.UserId))
+                .ToListAsync();
+            return wallets;
+        }
+
+        /// <summary>
+        /// 鏌ヨ浼佷笟閽卞寘
+        /// </summary>
+        /// <param name="enterpriseIds"></param>
+        /// <returns></returns>
+        private async Task<List<EnterpriseWallet>> GetEnterpriseWallets(List<Guid> enterpriseIds)
+        {
+            var wallets = await repEnterpriseWallet.AsQueryable()
+                .Where(it => enterpriseIds.Contains(it.EnterpriseId) && it.Access == EnumEnterpriseWalletAccess.Alipay)
+                .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.UpdateNowAsync(wallet);
+            }
+            return wallets;
+        }
+
+        /// <summary>
+        /// 鏌ヨ浠诲姟鐢ㄦ埛
+        /// </summary>
+        /// <param name="taskIds"></param>
+        /// <returns></returns>
+        private async Task<List<TaskInfoUser>> GetTaskUsers(List<Guid> taskIds)
+        {
+            var taskUsers = await repTaskInfoUser
+                .Include(it => it.EnterpriseEmployee)
+                .Where(it =>
+                    taskIds.Contains(it.TaskInfoId)
+                    && it.SettlementStatus == EnumTaskSettlementStatus.InProcess)
+                .ToListAsync();
+            return taskUsers;
+        }
+
+        /// <summary>
+        /// 鏌ヨ浠诲姟
+        /// </summary>
+        /// <param name="env"></param>
+        /// <returns></returns>
+        private async Task<List<TaskInfo>> GetTasks(string env)
+        {
+            var now = DateTime.Now;
+            var q = rep.AsQueryable()
+                .Include(it => it.Enterprise)
+                .Where(it => it.SettlementStatus == EnumTaskSettlementStatus.InProcess);
+            var minTime = env == "Test"
+                ? now.AddMinutes(-5)
+                : now.AddDays(-1);
+            q = q.Where(it => it.SettlementStartTime.HasValue && it.SettlementStartTime < minTime);
+            var tasks = await q.ToListAsync();
+            return tasks;
+        }
+
         private async Task SetCode(EnterpriseWalletTransaction entity)
         {
             entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}";
@@ -161,5 +358,16 @@
             }
         }
 
+        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);
+            }
+        }
+
     }
 }

--
Gitblit v1.9.1