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);
}
}
}
}