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
|
{
|
/// <summary>
|
/// 企业钱包命令处理器
|
/// </summary>
|
public class EnterpriseWalletCommandHandler(
|
IRepository<EnterpriseWallet> rep,
|
IRepository<EnterpriseWalletTransaction> repEnterpriseWalletTransaction,
|
IRepository<Enterprise> repEnterprise,
|
AlipayUtils alipayUtils
|
) :
|
IRequestHandler<OpenEnterpriseWalletCommand, OpenEnterpriseWalletCommandResult>,
|
IRequestHandler<CloseEnterpriseWalletCommand, Guid>,
|
IRequestHandler<RechargeEnterpriseWalletCommand, RechargeEnterpriseWalletCommandResult>
|
{
|
private readonly IRepository<EnterpriseWallet> rep = rep;
|
private readonly IRepository<Enterprise> repEnterprise = repEnterprise;
|
private readonly AlipayUtils alipayUtils = alipayUtils;
|
|
/// <summary>
|
/// 开通企业钱包
|
/// </summary>
|
/// <param name="request"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<OpenEnterpriseWalletCommandResult> 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;
|
}
|
|
/// <summary>
|
/// 关闭企业钱包
|
/// </summary>
|
/// <param name="request"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<Guid> 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;
|
}
|
|
/// <summary>
|
/// 企业钱包充值
|
/// </summary>
|
/// <param name="request"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
[UnitOfWork(false)]
|
public async Task<RechargeEnterpriseWalletCommandResult> 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);
|
}
|
}
|
}
|
}
|