using Aop.Api.Domain; using Azure; using FlexJobApi.Core; using Furion.DatabaseAccessor; using Furion.DistributedIDGenerator; using Furion.FriendlyException; using MediatR; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.UserServer.Application { /// /// 企业钱包命令处理器 /// public class EnterpriseWalletCommandHandler( IRepository rep, IRepository repEnterpriseWalletTransaction, IRepository repEnterprise, AlipayUtils alipayUtils ) : IRequestHandler, IRequestHandler, IRequestHandler { private readonly IRepository rep = rep; private readonly IRepository repEnterprise = repEnterprise; private readonly AlipayUtils alipayUtils = alipayUtils; /// /// 开通企业钱包 /// /// /// /// public async Task Handle(OpenEnterpriseWalletCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } if (request.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "请填写企业Id"); var enterprise = await repEnterprise.AsQueryable().AsNoTracking() .Where(it => it.Id == request.EnterpriseId) .FirstOrDefaultAsync(); if (enterprise == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业"); if (!enterprise.IsReal) throw Oops.Oh(EnumErrorCodeType.s510, "请先实名"); var entity = await rep.AsQueryable() .Where(it => it.EnterpriseId == request.EnterpriseId && it.Access == request.Access) .FirstOrDefaultAsync(); if (entity == null) { entity = new EnterpriseWallet(); entity.EnterpriseId = request.EnterpriseId!.Value; entity.Access = EnumEnterpriseWalletAccess.Alipay; entity.PersonalProductCode = "FUND_SAFT_SIGN_WITHHOLDING_P"; entity.SignScene = "INDUSTRY|SATF_ACC"; entity.ThirdPartyType = "PARTNER"; entity.ProductCode = "FUND_SAFT_SIGN_WITHHOLDING"; entity.SignStatus = EnumEnterpriseWalletSignStatus.Apply; await SetCode(entity); await rep.InsertAsync(entity); } else { if (entity.SignStatus == EnumEnterpriseWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s510, "已签约"); entity.SignStatus = EnumEnterpriseWalletSignStatus.Apply; await rep.UpdateAsync(entity); } var model = new AlipayUserAgreementPageSignModel(); model.ExternalLogonId = enterprise.Id.ToString(); model.PersonalProductCode = entity.PersonalProductCode; model.SignScene = entity.SignScene; model.ExternalAgreementNo = entity.Code; model.ThirdPartyType = entity.ThirdPartyType; model.ProductCode = entity.ProductCode; model.AccessParams = new AccessParams { Channel = "QRCODE" }; var response = alipayUtils.UserAgreementPageSign(model, $"/api/user/enterpriseWallet/alipayUserAgreementPageSignNotify"); if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg); var result = new OpenEnterpriseWalletCommandResult(); result.SignUrl = response.Body; return result; } /// /// 关闭企业钱包 /// /// /// /// public async Task Handle(CloseEnterpriseWalletCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } if (request.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "请填写企业Id"); var entity = await rep.AsQueryable() .Where(it => it.EnterpriseId == request.EnterpriseId && it.Access == request.Access) .FirstOrDefaultAsync(); if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包"); if (entity.SignStatus != EnumEnterpriseWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s510, "未签约"); var response = alipayUtils.UserAgreementUnsign(new AlipayUserAgreementUnsignModel { ExternalAgreementNo = entity.Code, PersonalProductCode = entity.PersonalProductCode, SignScene = entity.SignScene }); if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg); entity.SignStatus = EnumEnterpriseWalletSignStatus.Stop; return entity.Id; } /// /// 企业钱包充值 /// /// /// /// /// [UnitOfWork(false)] public async Task Handle(RechargeEnterpriseWalletCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } if (request.EnterpriseId == null) throw Oops.Oh(EnumErrorCodeType.s400, "请填写企业Id"); var entity = await rep.AsQueryable() .Where(it => it.EnterpriseId == request.EnterpriseId && it.Access == request.Access) .FirstOrDefaultAsync(); if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "企业钱包"); if (entity.SignStatus != EnumEnterpriseWalletSignStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s510, "未签约"); if (entity.AccountBookStatus != EnumEnterpriseWalletAccountBookStatus.Normal) throw Oops.Oh(EnumErrorCodeType.s510, "未开通记账本"); await GetBalance(entity); var order = new EnterpriseWalletTransaction(); order.Type = EnumEnterpriseWalletTransactionType.Recharge; order.WalletId = entity.Id; order.Amount = request.Amount; order.Remark = request.Remark ?? "充值"; order.ProductCode = "FUND_ACCOUNT_BOOK"; order.BizScene = "SATF_DEPOSIT"; order.TransactionStatus = EnumWalletTransactionStatus.WaitSubmit; order.Balance = entity.Balance; order.OperatorUserId = logier.Id; order.OperatorTime = DateTime.Now; await SetCode(order); await repEnterpriseWalletTransaction.InsertAsync(order); var response = alipayUtils.FundTransPagePay(new AlipayFundTransPagePayModel { OutBizNo = order.Code, TransAmount = order.Amount.ToString(), ProductCode = order.ProductCode, BizScene = order.BizScene, Remark = order.Remark, OrderTitle = order.Remark, TimeExpire = DateTime.Now.AddMinutes(15).ToString("yyyy-MM-dd HH:mm"), PayeeInfo = new Participant { IdentityType = "ACCOUNT_BOOK_ID", Identity = entity.AccountBookId, ExtInfo = new { agreement_no = entity.AgreementNo, }.ToJson(), }, }, "/api/user/enterpriseWallet/alipayFundTransOrderChangedNotify"); if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg); order.TransactionStatus = EnumWalletTransactionStatus.WaitPay; await repEnterpriseWalletTransaction.UpdateAsync(order); return new RechargeEnterpriseWalletCommandResult { PayUrl = response.Body }; } private async Task GetBalance(EnterpriseWallet entity) { var response = alipayUtils.FundAccountbookQuery(new AlipayFundAccountbookQueryModel { AccountBookId = entity.AccountBookId, SceneCode = "SATF_FUND_BOOK", MerchantUserId = entity.Code, }); if (response.IsError) throw Oops.Oh(EnumErrorCodeType.s510, response.SubMsg ?? response.Msg); entity.Balance = response.AvailableAmount.ToDecimal() ?? 0; await rep.UpdateNowAsync(entity); } private async Task SetCode(EnterpriseWalletTransaction entity) { entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; var exist = await repEnterpriseWalletTransaction.AsQueryable().AsNoTracking() .AnyAsync(it => it.Code == entity.Code); if (exist) { await SetCode(entity); } } private async Task SetCode(EnterpriseWallet entity) { entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; var exist = await rep.AsQueryable().AsNoTracking() .AnyAsync(it => it.Code == entity.Code); if (exist) { await SetCode(entity); } } } }