| 2025-11-19 | sunpengfei | ![]() |
| 2025-11-19 | sunpengfei | ![]() |
| 2025-11-19 | sunpengfei | ![]() |
ApiTools.Application/ApiTools.Application.xml
@@ -149,6 +149,64 @@ <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.ChannelWalletCommandHandler.Handle(ApiTools.Core.SaveChannelPingAnPayWalletCommand,System.Threading.CancellationToken)"> <summary> 保存渠道平安银行钱包 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.ChannelWalletCommandHandler.Handle(ApiTools.Core.SubmitChannelWalletTransferCommand,System.Threading.CancellationToken)"> <summary> 提交渠道钱包转账 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="T:ApiTools.Application.ChannelWalletQueryHandler"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="M:ApiTools.Application.ChannelWalletQueryHandler.#ctor(ApiTools.Core.ChannelWalletRepository,ApiTools.Core.ChannelWalletTransactionRepository)"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="M:ApiTools.Application.ChannelWalletQueryHandler.Handle(ApiTools.Core.GetChannelPingAnPayWalletQuery,System.Threading.CancellationToken)"> <summary> 查询渠道平安银行钱包 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.ChannelWalletQueryHandler.Handle(ApiTools.Core.GetChannelWalletTransactionQuery,System.Threading.CancellationToken)"> <summary> 查询渠道钱包交易详情 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.SendSmsCommandHandler.Handle(ApiTools.Core.SendSmsCommand,System.Threading.CancellationToken)"> <summary> 发送短信 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.SendSmsCommandHandler.Handle(ApiTools.Core.CheckVerifyCodeSmsCommand,System.Threading.CancellationToken)"> <summary> 校验验证码 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="T:ApiTools.CommonServer.Application.SaveSmsSettingCommandHandler"> <summary> 保存短信配置 @@ -216,22 +274,6 @@ <member name="M:ApiTools.CommonServer.Application.GetSmsSettingQueryHandler.Handle(ApiTools.Core.GetSmsSettingQuery,System.Threading.CancellationToken)"> <summary> 查询短信配置 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.SendSmsCommandHandler.Handle(ApiTools.Core.SendSmsCommand,System.Threading.CancellationToken)"> <summary> 发送短信 </summary> <param name="request"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Application.SendSmsCommandHandler.Handle(ApiTools.Core.CheckVerifyCodeSmsCommand,System.Threading.CancellationToken)"> <summary> 校验验证码 </summary> <param name="request"></param> <param name="cancellationToken"></param> ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
New file @@ -0,0 +1,135 @@ using 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, }; } } } ApiTools.Application/ChannelWallets/Queries/ChannelWalletQueryHandler.cs
New file @@ -0,0 +1,55 @@ using ApiTools.Core; using Mapster; using MediatR; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Application { /// <summary> /// 查询渠道钱包交易详情 /// </summary> public class ChannelWalletQueryHandler( ChannelWalletRepository channelWalletRepository, ChannelWalletTransactionRepository channelWalletTransactionRepository ) : IRequestHandler<GetChannelPingAnPayWalletQuery, GetChannelPingAnPayWalletQueryResult>, IRequestHandler<GetChannelWalletTransactionQuery, GetChannelWalletTransactionQueryResult> { private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository; private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository; /// <summary> /// 查询渠道平安银行钱包 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<GetChannelPingAnPayWalletQueryResult> Handle(GetChannelPingAnPayWalletQuery request, CancellationToken cancellationToken) { return await channelWalletRepository.GetQueryable() .Where(it => it.OutWalletId == request.OutWalletId) .ProjectToType<GetChannelPingAnPayWalletQueryResult>() .FirstOrDefaultAsync(); } /// <summary> /// 查询渠道钱包交易详情 /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<GetChannelWalletTransactionQueryResult> Handle(GetChannelWalletTransactionQuery request, CancellationToken cancellationToken) { return await channelWalletTransactionRepository.GetQueryable() .Where(it => it.OutCode == request.OutCode) .ProjectToType<GetChannelWalletTransactionQueryResult>() .FirstOrDefaultAsync(); } } } ApiTools.Core/ApiTools.Core.csproj
@@ -19,6 +19,8 @@ <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.14.1" /> <PackageReference Include="Baidu.AI" Version="4.15.16" /> <PackageReference Include="Consul" Version="1.7.14.8" /> <PackageReference Include="DistributedLock.Core" Version="1.0.8" /> <PackageReference Include="DistributedLock.Redis" Version="1.1.0" /> <PackageReference Include="EFCore.BulkExtensions" Version="9.0.1" /> <PackageReference Include="Furion" Version="4.9.7.106" /> <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.7.106" /> ApiTools.Core/ApiTools.Core.xml
@@ -809,6 +809,411 @@ 是否禁用 </summary> </member> <member name="T:ApiTools.Core.ChannelWallet"> <summary> 渠道钱包 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.ChannelId"> <summary> 渠道Id </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Channel"> <summary> 渠道 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.OutWalletId"> <summary> 外部钱包Id </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Access"> <summary> 通道 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Code"> <summary> 编号 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Bank"> <summary> 所属银行 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.BankBranch"> <summary> 所属支行 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Name"> <summary> 户名 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Identity"> <summary> 账号 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.Balance"> <summary> 余额 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.SignStatus"> <summary> 签约状态 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.ErrorCode"> <summary> 错误代码 </summary> </member> <member name="P:ApiTools.Core.ChannelWallet.FailReason"> <summary> 返回具体的原因。 </summary> </member> <member name="T:ApiTools.Core.ChannelWalletTransaction"> <summary> 渠道钱包交易 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.WalletId"> <summary> 钱包Id </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Wallet"> <summary> 钱包 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.PingAnPay"> <summary> 平安信息 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Type"> <summary> 类型 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Code"> <summary> 订单号 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.OutCode"> <summary> 外部订单号 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ConcurrencyLock"> <summary> 并发锁 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Amount"> <summary> 金额 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Balance"> <summary> 余额 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.AfterBalance"> <summary> 收支后余额 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.OutOperatorId"> <summary> 外部操作人Id </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.OperatorTime"> <summary> 操作时间 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.PayerAccount"> <summary> 付款人账户 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.PayerName"> <summary> 付款人名称 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.PayerBank"> <summary> 付款人开户行 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.PayerBankBranch"> <summary> 付款人支行 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.OutReceiveId"> <summary> 外部收款人Id </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ReceiveName"> <summary> 收款人姓名 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ReceiveIdentity"> <summary> 收款人身份证号 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ReceiveBank"> <summary> 收款人开户行 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ReceiveBankBranch"> <summary> 收款人支行 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Currency"> <summary> 币种 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Purpose"> <summary> 用途 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.Remark"> <summary> 备注 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.ErrorCode"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.FailReason"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.TransDate"> <summary> 订单支付时间 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.OrderFee"> <summary> 预计收费金额(元),转账到银行卡专用 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.EreceiptFileId"> <summary> 电子收据Id </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.EreceiptDownloadUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.EreceiptDownloadOssUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.EreceiptStatus"> <summary> 电子收据状态 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.EreceiptErrorMessage"> <summary> 电子收据错误信息 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransaction.TransactionStatus"> <summary> 状态 </summary> </member> <member name="T:ApiTools.Core.ChannelWalletTransactionPingAnPay"> <summary> 渠道钱包交易记录平安支付信息 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.Transaction"> <summary> 交易 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.FreezeNo"> <summary> 止付编号 有效状态的平安易止付编号,从JGF001止付后返回的 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.StopStt"> <summary> 止付状态码 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.StopFailReason"> <summary> 止付失败原因 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.RemoveStopStt"> <summary> 解除止付状态码 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.RemoveStopFailReason"> <summary> 解除止付失败原因 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.ThirdVoucher"> <summary> 转账凭证号 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.FrontLogNo"> <summary> 银行流水号 银行业务流水号;可以用于对账 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.CstInnerFlowNo"> <summary> 客户自定义凭证号 用于客户转账登记和内部识别,通过转账结果查询可以返回。银行不检查唯一性 </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.IsBack"> <summary> 转账退票标志 "0:未退票; 默认为0 1:退票;" 数据长度:1,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.BackRem"> <summary> 支付失败或退票原因描述 "如果是超级网银则返回如下信息: RJ01对方返回:账号不存在 RJ02对方返回:账号、户名不符 大小额支付则返回失败描述" 数据长度:20,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.Yhcljg"> <summary> 银行处理结果 "格式为:“六位代码:中文描述”。冒号为半角。如:000000:转账成功 处理中的返回(以如下返回开头): MA9111:交易正在受理中 000000:交易受理成功待处理 000000:交易处理中 000000:交易受理成功处理中 成功的返回: 000000:转账交易成功 其他的返回都为失败: MA9112:转账失败" 数据长度:40,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.SysFlag"> <summary> 转账加急标志 Y:加急 N:普通S:特急 数据长度:1,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.Fee"> <summary> 转账手续费 数据长度:13,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.TransBsn"> <summary> 转账代码类型 "4004:单笔转账; 4014:单笔批量; 4034:汇总批量" 数据长度:4,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.SubmitTime"> <summary> 交易受理时间 交易受理时间 数据长度:14,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.AccountDate"> <summary> 记账日期 主机记账日期 数据长度:8,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.HostFlowNo"> <summary> 主机记账流水号 主机记账流水 数据长度:32,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.HostErrorCode"> <summary> 错误码 交易失败的错误代码 数据长度:20,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.ProxyPayName"> <summary> 代理人户名 用于代理行支付功能 数据长度:60,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.ProxyPayAcc"> <summary> 代理人账号 用于代理行支付功能 数据长度:30,是否必输:N </summary> </member> <member name="P:ApiTools.Core.ChannelWalletTransactionPingAnPay.ProxyPayBankName"> <summary> 代理人银行名称 用于代理行支付功能 数据长度:30,是否必输:N </summary> </member> <member name="T:ApiTools.Core.User"> <summary> 用户 @@ -1115,6 +1520,11 @@ 渠道信息 </summary> </member> <member name="F:ApiTools.Core.EnumResourceController.UserServerChannelWallet"> <summary> 渠道钱包 </summary> </member> <member name="F:ApiTools.Core.EnumResourceController.UserServerChannelUser"> <summary> 渠道用户 @@ -1402,6 +1812,121 @@ 运营 </summary> </member> <member name="T:ApiTools.Core.EnumWalletAccess"> <summary> 渠道钱包通道 </summary> </member> <member name="F:ApiTools.Core.EnumWalletAccess.Alipay"> <summary> 支付宝 </summary> </member> <member name="F:ApiTools.Core.EnumWalletAccess.PingAnPay"> <summary> 平安银行 </summary> </member> <member name="F:ApiTools.Core.EnumWalletAccess.WeChatPay"> <summary> 微信 </summary> </member> <member name="T:ApiTools.Core.EnumWalletSignStatus"> <summary> 渠道钱包签约状态 </summary> </member> <member name="F:ApiTools.Core.EnumWalletSignStatus.Wait"> <summary> 未签约 </summary> </member> <member name="F:ApiTools.Core.EnumWalletSignStatus.Apply"> <summary> 申请中 </summary> </member> <member name="F:ApiTools.Core.EnumWalletSignStatus.Normal"> <summary> 已签约 </summary> </member> <member name="F:ApiTools.Core.EnumWalletSignStatus.Stop"> <summary> 终止 </summary> </member> <member name="T:ApiTools.Core.EnumWalletTransactionEreceiptStatus"> <summary> 钱包交易电子收据状态 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionEreceiptStatus.INIT"> <summary> 初始化 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionEreceiptStatus.PROCESS"> <summary> 处理中 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionEreceiptStatus.SUCCESS"> <summary> 成功 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionEreceiptStatus.FAIL"> <summary> 失败 </summary> </member> <member name="T:ApiTools.Core.EnumWalletTransactionStatus"> <summary> 钱包交易状态 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionStatus.WaitSubmit"> <summary> 待提交 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionStatus.WaitPay"> <summary> 待支付 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionStatus.Dealing"> <summary> 处理中 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionStatus.Success"> <summary> 成功 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionStatus.Refund"> <summary> 退票 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionStatus.Fail"> <summary> 失败 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionType.Recharge"> <summary> 充值 </summary> </member> <member name="F:ApiTools.Core.EnumWalletTransactionType.Transfer"> <summary> 转账 </summary> </member> <member name="T:ApiTools.Core.IIsDisabled"> <summary> 是否已禁用 @@ -1446,6 +1971,16 @@ <member name="P:ApiTools.Core.ITreeData`1.Code"> <summary> 编号 </summary> </member> <member name="T:ApiTools.Core.RefreshChannelWalletTransactionStatusJob"> <summary> 刷新渠道钱包交易状态 </summary> </member> <member name="M:ApiTools.Core.RefreshChannelWalletTransactionStatusJob.#ctor(ApiTools.Core.ChannelWalletRepository,ApiTools.Core.ChannelWalletTransactionRepository,ApiTools.Core.ChannelWalletService)"> <summary> 刷新渠道钱包交易状态 </summary> </member> <member name="T:ApiTools.Core.ChangePhoneNumberCommand"> @@ -1714,6 +2249,351 @@ </summary> </member> <member name="P:ApiTools.Core.GetChannelUsersQueryResultItem.Status"> <summary> 状态 </summary> </member> <member name="T:ApiTools.Core.SaveChannelPingAnPayWalletCommand"> <summary> 保存渠道平安银行钱包 </summary> </member> <member name="P:ApiTools.Core.SaveChannelPingAnPayWalletCommand.OutWalletId"> <summary> 外部钱包Id </summary> </member> <member name="P:ApiTools.Core.SaveChannelPingAnPayWalletCommand.Name"> <summary> 户名 </summary> </member> <member name="P:ApiTools.Core.SaveChannelPingAnPayWalletCommand.Identity"> <summary> 账号 </summary> </member> <member name="P:ApiTools.Core.SaveChannelPingAnPayWalletCommandResult.Id"> <summary> 钱包Id </summary> </member> <member name="P:ApiTools.Core.SaveChannelPingAnPayWalletCommandResult.Balance"> <summary> 余额 </summary> </member> <member name="T:ApiTools.Core.SubmitChannelWalletTransferCommand"> <summary> 提交渠道钱包转账 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.OutWalletId"> <summary> 外部钱包Id </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.OutCode"> <summary> 外部订单号 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.OutOperatorId"> <summary> 外部操作人Id </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.OperatorTime"> <summary> 操作时间 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.OutReceiveId"> <summary> 外部收款人Id </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.Amount"> <summary> 金额 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.ReceiveName"> <summary> 收款人姓名 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.ReceiveIdentity"> <summary> 收款人身份证号 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.ReceiveBank"> <summary> 收款人开户行 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.ReceiveBankBranch"> <summary> 收款人支行 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.Currency"> <summary> 币种 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.Purpose"> <summary> 用途 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommand.Remark"> <summary> 备注 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommandResult.Id"> <summary> 交易Id </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommandResult.Code"> <summary> 订单号 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommandResult.TransactionStatus"> <summary> 状态 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommandResult.ErrorCode"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 </summary> </member> <member name="P:ApiTools.Core.SubmitChannelWalletTransferCommandResult.FailReason"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 </summary> </member> <member name="T:ApiTools.Core.GetChannelPingAnPayWalletQuery"> <summary> 查询渠道平安银行钱包 </summary> </member> <member name="P:ApiTools.Core.GetChannelPingAnPayWalletQuery.OutWalletId"> <summary> 外部钱包Id </summary> </member> <member name="T:ApiTools.Core.GetChannelPingAnPayWalletQueryResult"> <summary> 查询渠道平安银行钱包 </summary> </member> <member name="P:ApiTools.Core.GetChannelPingAnPayWalletQueryResult.Id"> <summary> 钱包Id </summary> </member> <member name="P:ApiTools.Core.GetChannelPingAnPayWalletQueryResult.Name"> <summary> 户名 </summary> </member> <member name="P:ApiTools.Core.GetChannelPingAnPayWalletQueryResult.Identity"> <summary> 账号 </summary> </member> <member name="P:ApiTools.Core.GetChannelPingAnPayWalletQueryResult.Balance"> <summary> 余额 </summary> </member> <member name="T:ApiTools.Core.GetChannelWalletTransactionQuery"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQuery.OutCode"> <summary> 外部订单号 </summary> </member> <member name="T:ApiTools.Core.GetChannelWalletTransactionQueryResult"> <summary> 查询渠道钱包交易详情 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Id"> <summary> 交易Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Type"> <summary> 类型 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Code"> <summary> 订单号 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.OutCode"> <summary> 外部订单号 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ConcurrencyLock"> <summary> 并发锁 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Amount"> <summary> 金额 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Balance"> <summary> 余额 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.AfterBalance"> <summary> 收支后余额 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.OutOperatorId"> <summary> 外部操作人Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.OperatorTime"> <summary> 操作时间 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.PayerAccount"> <summary> 付款人账户 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.PayerName"> <summary> 付款人名称 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.PayerBank"> <summary> 付款人开户行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.PayerBankBranch"> <summary> 付款人支行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.OutReceiveId"> <summary> 外部收款人Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ReceiveName"> <summary> 收款人姓名 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ReceiveIdentity"> <summary> 收款人身份证号 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ReceiveAccount"> <summary> 收款账户 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ReceiveBank"> <summary> 收款人开户行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ReceiveBankBranch"> <summary> 收款人支行 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Currency"> <summary> 币种 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Purpose"> <summary> 用途 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.Remark"> <summary> 备注 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.ErrorCode"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.FailReason"> <summary> 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.TransDate"> <summary> 订单支付时间 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.OrderFee"> <summary> 预计收费金额(元),转账到银行卡专用 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.EreceiptFileId"> <summary> 电子收据Id </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.EreceiptDownloadUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.EreceiptDownloadOssUrl"> <summary> 电子收据下载链接 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.EreceiptStatus"> <summary> 电子收据状态 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.EreceiptErrorMessage"> <summary> 电子收据错误信息 </summary> </member> <member name="P:ApiTools.Core.GetChannelWalletTransactionQueryResult.TransactionStatus"> <summary> 状态 </summary> @@ -2157,6 +3037,231 @@ <summary> 签名名称 </summary> </member> <member name="M:ApiTools.Core.BaseRepository`2.GetQueryable(System.Boolean)"> <summary> 获取查询 </summary> <param name="noTracking"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.GetQueryable(System.Boolean,System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}})"> <summary> 获取查询 </summary> <param name="noTracking"></param> <param name="query"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.Get(System.Guid,System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}},System.Threading.CancellationToken)"> <summary> 获取实体 </summary> <param name="id"></param> <param name="query"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.Get(System.Collections.Generic.List{System.Guid},System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}},System.Threading.CancellationToken)"> <summary> 获取实体 </summary> <param name="ids"></param> <param name="query"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.GetSelect``2(ApiTools.Core.SelectQuery{``0,``1},System.Func{``1,``0},System.Func{``1,System.String},System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}},System.Threading.CancellationToken)"> <summary> 查询选择器数据 </summary> <typeparam name="TValue"></typeparam> <typeparam name="TData"></typeparam> <param name="request"></param> <param name="getValue"></param> <param name="getLabel"></param> <param name="query"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.SetIsDisabled(ApiTools.Core.SetIsDisabledCommand,System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}},System.Threading.CancellationToken)"> <summary> 设置是否禁用 </summary> <param name="request"></param> <param name="query"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.DeleteData(ApiTools.Core.DeleteDataCommand,System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}},System.Threading.CancellationToken)"> <summary> 删除数据 </summary> <param name="request"></param> <param name="query"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.UpdateData``1(System.Linq.IQueryable{`0},``0,System.Action{`0},System.Threading.CancellationToken)"> <summary> 更新数据 </summary> <typeparam name="TRequest"></typeparam> <param name="q"></param> <param name="request"></param> <param name="update"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="M:ApiTools.Core.BaseRepository`2.SaveData``1(``0,System.Func{System.Linq.IQueryable{`0},System.Linq.IQueryable{`0}},System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Action{`0},System.Threading.CancellationToken)"> <summary> 保存数据 </summary> <typeparam name="TRequest"></typeparam> <param name="request"></param> <param name="query"></param> <param name="checkExist"></param> <param name="update"></param> <param name="cancellationToken"></param> <returns></returns> </member> <member name="T:ApiTools.Core.ChannelWalletRepository"> <summary> 企业钱包仓库 </summary> </member> <member name="M:ApiTools.Core.ChannelWalletRepository.SetCode(ApiTools.Core.ChannelWallet)"> <summary> 设置编号 </summary> <param name="entity"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelWalletTransactionRepository.SetCode(ApiTools.Core.ChannelWalletTransaction)"> <summary> 设置编号 </summary> <param name="entity"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelPingAnPayWalletService.GetEnterpriseWalletBalance(ApiTools.Core.ChannelWallet)"> <summary> 查询企业钱包余额 </summary> <param name="wallet"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelPingAnPayWalletService.Transfer(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 转账 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelPingAnPayWalletService.GetTransactionDetail(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 查询交易记录 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelPingAnPayWalletService.DownloadEreceiptUrl(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 下载电子收据 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="T:ApiTools.Core.ChannelWalletService"> <summary> 渠道钱包服务 </summary> <param name="channelWalletRepository"></param> <param name="channelPingAnPayWalletService"></param> </member> <member name="M:ApiTools.Core.ChannelWalletService.#ctor(ApiTools.Core.ChannelWalletRepository,ApiTools.Core.ChannelPingAnPayWalletService)"> <summary> 渠道钱包服务 </summary> <param name="channelWalletRepository"></param> <param name="channelPingAnPayWalletService"></param> </member> <member name="M:ApiTools.Core.ChannelWalletService.GetEnterpriseWallet(System.String)"> <summary> 查询企业钱包余额 </summary> <param name="outWalletId"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelWalletService.GetEnterpriseWalletBalance(ApiTools.Core.ChannelWallet)"> <summary> 查询企业钱包余额 </summary> <param name="wallet"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelWalletService.Transfer(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 转账 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelWalletService.GetTransactionDetail(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 查询交易记录 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="M:ApiTools.Core.ChannelWalletService.DownloadEreceiptUrl(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 下载电子收据 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="T:ApiTools.Core.IChannelWalletService"> <summary> 渠道钱包服务 </summary> </member> <member name="M:ApiTools.Core.IChannelWalletService.GetEnterpriseWalletBalance(ApiTools.Core.ChannelWallet)"> <summary> 查询渠道钱包余额 </summary> <param name="wallet"></param> <returns></returns> </member> <member name="M:ApiTools.Core.IChannelWalletService.Transfer(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 转账 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="M:ApiTools.Core.IChannelWalletService.GetTransactionDetail(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 查询交易记录 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="M:ApiTools.Core.IChannelWalletService.DownloadEreceiptUrl(ApiTools.Core.ChannelWallet,ApiTools.Core.ChannelWalletTransaction)"> <summary> 下载电子收据 </summary> <param name="wallet"></param> <param name="transaction"></param> <returns></returns> </member> <member name="T:ApiTools.Core.AlipayUtils"> <summary> @@ -3858,460 +4963,6 @@ 数据长度:30,是否必输:N </summary> </member> <member name="T:ApiTools.Core.HistoryBalanceQueryRequest"> <summary> 历史余额查询_银企直联 </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryRequest.Account"> <summary> 账号 </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryRequest.RptDate"> <summary> 历史日期 yyyyMMdd限制查询当前日期的前360天内的 </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryRequest.Reserve"> <summary> 保留域 </summary> </member> <member name="T:ApiTools.Core.HistoryBalanceQueryResponse"> <summary> 历史余额查询_银企直联 </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.AcctNo"> <summary> 账号 数据长度:20,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.CcyCode"> <summary> 币种 数据长度:3,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.BeginDate"> <summary> 开始日期 "若查询当日明细,开始、结束日期必须为当天;若查询历史明细,开始、结束日期必须是历史日期。 格式yyyyMMdd" 数据长度:8,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.EndDate"> <summary> 结束日期 格式yyyyMMdd 数据长度:8,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.PageNo"> <summary> 查询页码 1:第一页,依次递增 数据长度:6,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.PageSize"> <summary> 每页明细数量 "当日明细默认每页30条记录,支持最大每页100条,若上送PageSize>100无效,等同100; 历史明细默认每页30条记录,支持最大每页1000条,若上送PageSize>1000则提示输入错误; 且每次查询必须固定为此值,否则出现明细遗漏" 数据长度:6,是否必输:N </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.Reserve"> <summary> 预留字段 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.OrderMode"> <summary> 记录排序标志 "001:按交易时间降序; 002:按交易时间升序; 说明: ① 当为历史交易明细查询时,默认按照001:按交易时间降序; ② 当为当日明细查询时,默认按照002:按交易时间升序; (注:当日明细在交易量大的情况下,必须采用正序查询,否则会导致交易遗漏和重复)" 数据长度:3,是否必输:N </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.BankTranFlowNo"> <summary> 银行交易流水号 输入则查询过滤指定条件的记录 数据长度:30,是否必输:N </summary> </member> <member name="P:ApiTools.Core.HistoryBalanceQueryResponse.OppAcctNo"> <summary> 交易对手账号 输入则查询过滤指定条件的记录 数据长度:30,是否必输:N </summary> </member> <member name="T:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest"> <summary> 查询账户当日历史交易明细_银企直联 </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.AcctNo"> <summary> 账号 数据长度:20,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.CcyCode"> <summary> 币种 数据长度:3,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.BeginDate"> <summary> 开始日期 "若查询当日明细,开始、结束日期必须为当天;若查询历史明细,开始、结束日期必须是历史日期。 格式yyyyMMdd" 数据长度:8,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.EndDate"> <summary> 结束日期 格式yyyyMMdd 数据长度:8,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.PageNo"> <summary> 查询页码 1:第一页,依次递增 数据长度:6,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.PageSize"> <summary> 每页明细数量 "当日明细默认每页30条记录,支持最大每页100条,若上送PageSize>100无效,等同100; 历史明细默认每页30条记录,支持最大每页1000条,若上送PageSize>1000则提示输入错误; 且每次查询必须固定为此值,否则出现明细遗漏" 数据长度:6,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.Reserve"> <summary> 预留字段 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.OrderMode"> <summary> 记录排序标志 "001:按交易时间降序; 002:按交易时间升序; 说明: ① 当为历史交易明细查询时,默认按照001:按交易时间降序; ② 当为当日明细查询时,默认按照002:按交易时间升序; (注:当日明细在交易量大的情况下,必须采用正序查询,否则会导致交易遗漏和重复)" 数据长度:3,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.BankTranFlowNo"> <summary> 银行交易流水号 输入则查询过滤指定条件的记录 数据长度:30,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest.OppAcctNo"> <summary> 交易对手账号 输入则查询过滤指定条件的记录 数据长度:30,是否必输:N </summary> </member> <member name="T:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse"> <summary> 查询账户当日历史交易明细_银企直联 </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse.AcctNo"> <summary> 账号 数据长度:20,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse.CcyCode"> <summary> 货币类型 数据长度:3,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse.EndFlag"> <summary> 数据结束标志 "“Y”---表示查询结果已全部输出完毕; “N”---表示查询结果只输出一部分,后续部分有待请求输出;" 数据长度:1,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse.Reserve"> <summary> 预留字段 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse.PageNo"> <summary> 查询页码 同上送 数据长度:6,是否必输:Y </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponse.PageRecCount"> <summary> 记录笔数 本次返回的笔数 数据长度:2,是否必输:N </summary> </member> <member name="T:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem"> <summary> 查询账户当日历史交易明细_银企直联 </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.AcctDate"> <summary> 主机记账日期 记账日期 数据长度:8,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.TxTime"> <summary> 交易时间 数据长度:6,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.HostTrace"> <summary> 主机流水号 银行记账流水号 数据长度:32,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.BussSeqNo"> <summary> 业务流水号 银行业务流水号 数据长度:32,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.DetailSerialNo"> <summary> 明细序号 明细序号,原来和核心水号一起区分交易唯一性 数据长度:19,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.OutNode"> <summary> 付款方网点号 数据长度:9,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.OutBankNo"> <summary> 付款方联行号 数据长度:16,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.OutBankName"> <summary> 付款行名称 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.OutAcctNo"> <summary> 付款方账号 数据长度:32,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.OutAcctName"> <summary> 付款方户名 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.CcyCode"> <summary> 结算币种 数据长度:3,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.TranAmount"> <summary> 交易金额 数据长度:15,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.InNode"> <summary> 收款方网点号 数据长度:9,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.InBankNo"> <summary> 收款方联行号 数据长度:16,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.InBankName"> <summary> 收款方行名 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.InAcctNo"> <summary> 收款方账号 数据长度:32,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.InAcctName"> <summary> 收款方户名 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.DcFlag"> <summary> 借贷标志 D 借;C 贷 数据长度:1,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.AbstractStr"> <summary> 摘要,未翻译的摘要,如TRS 数据长度:120,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.VoucherNo"> <summary> 凭证号 空 数据长度:20,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.TranFee"> <summary> 手续费 数据长度:15,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.PostFee"> <summary> 邮电费 数据长度:15,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.AcctBalance"> <summary> 账面余额 数据长度:15,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.Purpose"> <summary> 用途,附言 客户转账上送的资金用途。 数据长度:300,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.AbstractStr_Desc"> <summary> 中文摘要,AbstractStr的中文翻译 数据长度:100,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.ProxyPayName"> <summary> 代理人户名 用于代理行支付功能 数据长度:100,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.ProxyPayAcc"> <summary> 代理人账号 用于代理行支付功能 数据长度:100,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.ProxyPayBankName"> <summary> 代理人银行名称 用于代理行支付功能 数据长度:100,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.HostDate"> <summary> 主机日期 交易自然日期 数据长度:8,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.TranSeqNo"> <summary> 交易流水号 数据长度:32,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.Remark1"> <summary> 备注1 数据长度:300,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.Remark2"> <summary> 备注2 数据长度:300,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.BeReverseFlag"> <summary> 被冲正标志 "0--无关; 1--被冲正; 2--冲正" 数据长度:2,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.SeqTime"> <summary> 时序时间 数据长度:30,是否必输:N </summary> </member> <member name="P:ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsResponseItem.FeeCode"> <summary> 费用代码 数据长度:20,是否必输:N </summary> </member> <member name="T:ApiTools.Core.InquiryAccountStopPaymentDetailsRequest"> <summary> 账户止付详情查询_银企直联 对公账户层的冻结/止付详情查询,每页最大100条。 @@ -4798,456 +5449,6 @@ 交易状态标志 20:交易成功 30:失败;其他为银行受理成功处理中,请使用“交易进度查询4005”接口获取最终状态 </summary> </member> <member name="T:ApiTools.Core.SingleDataQueryRequest"> <summary> 回单数据查询_银企直联 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.AcctNo"> <summary> 账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.ReceiptType"> <summary> 回单类型 参照回单类型 注:查全部可送“ALL” </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.SubType"> <summary> 子类型 参照回单类型 注:查全部可送“ALL” </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.StartDate"> <summary> 起始日期 格式yyyyMMdd(记账日期) </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.EndDate"> <summary> 结束日期 格式yyyyMMdd(记账日期) </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.StartRecord"> <summary> 起始记录数 起始值为1,不能送0 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.RecordNum"> <summary> 本批记录数 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.StartAmt"> <summary> 开始金额 (交易金额)double(20,4) </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.EntAmt"> <summary> 结束金额 (交易金额)double(20,5) </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.OrderMode"> <summary> 排序方式 001:交易时间从近到远 002:交易时间从远到近 003:金额升序(从小到大) 004:金额降序(从大到小) 005:回单号升序 006:回单号降序 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.PayeeAcctNo"> <summary> 收款人账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.PayeeName"> <summary> 收款人名称 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.DrCrFlag"> <summary> 借贷标志 D:借方交易 C:贷方交易 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.Ccy"> <summary> 币种 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.SerialNo"> <summary> 顺序号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.PrintBranchId"> <summary> 打印网点 代码里面没有 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.ReceiptNo"> <summary> 回单号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryRequest.PrintFlag"> <summary> 打印标志 0:首次打印 1:补打 </summary> </member> <member name="T:ApiTools.Core.SingleDataQueryResponse"> <summary> 回单数据查询_银企直联 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponse.RecordTotalCount"> <summary> 记录总数 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponse.StartRecord"> <summary> 起始记录数 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponse.ResultNum"> <summary> 本次返回记录数 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponse.EndFlag"> <summary> 结束标志 Y:无剩余记录 N:有剩余记录 </summary> </member> <member name="T:ApiTools.Core.SingleDataQueryResponseItem"> <summary> 回单数据查询_银企直联 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.ReceiptNo"> <summary> 回单号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.CheckCode"> <summary> 验证码 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.ReceiptType"> <summary> 回单类型 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.SubType"> <summary> 回单子类 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.BookingDate"> <summary> 记账日期 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayerName"> <summary> 付款人名称 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayeeName"> <summary> 收款人名称 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayerAccNo"> <summary> 付款人账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayeeAccNo"> <summary> 收款人账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayerAcctOpenBranchID"> <summary> 付款人开户行 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayeeAcctOpenBranchID"> <summary> 收款人开户行 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayerAcctOpenBranchName"> <summary> 付款人开户行名称 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PayeeAcctOpenBranchName"> <summary> 收款人开户行名称 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.MainAcctNo"> <summary> 主账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.SubAcctNo"> <summary> 子账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.OldAcctNo"> <summary> 原账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.Ccy"> <summary> 币种 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TranAmt"> <summary> 交易金额 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.SubBranchID"> <summary> 网点号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.DrCrFlag"> <summary> 借贷标志 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.Crpp"> <summary> 资金用途 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.Corpus"> <summary> 本金 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.DepositIntRate"> <summary> 存款利率 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.DepositReceiptNo"> <summary> 存单号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.StartPeriod"> <summary> 起始期 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.EndPeriod"> <summary> 结束期 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.InterestTax"> <summary> 利息税 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.IntInterest"> <summary> 利息 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.OverdraftInterest"> <summary> 透支利息 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TaxRate"> <summary> 税率 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.LoanAcctNo"> <summary> 贷款账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.DuebillNo"> <summary> 借据号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PaidAmt"> <summary> 还款金额 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.RepayCorpus"> <summary> 还款本金 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.ReplyInterest"> <summary> 还款利息 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.ComInterest"> <summary> 复利 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.CorpusBalance"> <summary> 本金余额 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.DueRepayCorpus"> <summary> 应还本金 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.RepayCount"> <summary> 还款期数 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.Commission"> <summary> 手续费金额 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.MaterialFee"> <summary> 工本费 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TaxedInterest"> <summary> 税后利息 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.HostSeqNo"> <summary> 主机流水号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.LoanIntRate"> <summary> 贷款利率 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.ReceivableInterest"> <summary> 应收利息 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TellerNo"> <summary> 柜员号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.AuthTellerNo"> <summary> 授权柜员号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PrintClientName"> <summary> 打印客户端名称 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PrintTime"> <summary> 打印时间 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PrintTimes"> <summary> 打印次数 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.RegionNo"> <summary> 地区号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TermNo"> <summary> 终端号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.PrintNote"> <summary> 打印节点 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.BussType"> <summary> 业务类型 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.IntSettleAcctNo"> <summary> 结息账号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.AcctOpenBranchID"> <summary> 账户开户行行号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TranDate"> <summary> 交易日期 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.TranTime"> <summary> 交易时间 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.BranchId"> <summary> 机构号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.SerialNo"> <summary> 顺序号 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.RecordType"> <summary> 记录类型 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.FrontEndCode"> <summary> 前置机代码 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.RemarkCode"> <summary> 摘要码 </summary> </member> <member name="P:ApiTools.Core.SingleDataQueryResponseItem.Summary"> <summary> 摘要 </summary> </member> <member name="T:ApiTools.Core.SingleOrBatchReceiptPDFMergeDownloadNewRequest"> <summary> 单笔或多笔回单PDF合并下载(新)_银企直联 @@ -5398,20 +5599,6 @@ <param name="request"></param> <returns></returns> </member> <member name="M:ApiTools.Core.PingAnPayUtils.HistoryBalanceQuery(ApiTools.Core.HistoryBalanceQueryRequest)"> <summary> 历史余额查询_银企直联 </summary> <param name="request"></param> <returns></returns> </member> <member name="M:ApiTools.Core.PingAnPayUtils.InquiryAccountDayHistoryTransactionDetails(ApiTools.Core.InquiryAccountDayHistoryTransactionDetailsRequest)"> <summary> 查询账户当日历史交易明细_银企直联 </summary> <param name="request"></param> <returns></returns> </member> <member name="M:ApiTools.Core.PingAnPayUtils.StopPaymentAndSettlementAccounts(ApiTools.Core.StopPaymentAndSettlementAccountsRequest)"> <summary> 账户止付和解止付_银企直联 对公账户层的止付、解除止付 @@ -5436,13 +5623,6 @@ <member name="M:ApiTools.Core.PingAnPayUtils.CorSingleTransferQuery(ApiTools.Core.CorSingleTransferQueryRequest)"> <summary> 单笔转账指令查询_银企直联 </summary> <param name="request"></param> <returns></returns> </member> <member name="M:ApiTools.Core.PingAnPayUtils.SingleDataQuery(ApiTools.Core.SingleDataQueryRequest)"> <summary> 当日历史回单数据查询接口_银企直联 </summary> <param name="request"></param> <returns></returns> ApiTools.Core/Entities/Users/ChannelWallet.cs
New file @@ -0,0 +1,81 @@ using Furion.DatabaseAccessor; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包 /// </summary> public class ChannelWallet : CommonEntity<MasterDbContextLocator> { /// <summary> /// 渠道Id /// </summary> public Guid? ChannelId { get; set; } /// <summary> /// 渠道 /// </summary> public Channel Channel { get; set; } /// <summary> /// 外部钱包Id /// </summary> public string OutWalletId { get; set; } /// <summary> /// 通道 /// </summary> public EnumWalletAccess Access { get; set; } /// <summary> /// 编号 /// </summary> public string Code { get; set; } /// <summary> /// 所属银行 /// </summary> public string Bank { get; set; } /// <summary> /// 所属支行 /// </summary> public string BankBranch { get; set; } /// <summary> /// 户名 /// </summary> public string Name { get; set; } /// <summary> /// 账号 /// </summary> public string Identity { get; set; } /// <summary> /// 余额 /// </summary> public decimal Balance { get; set; } /// <summary> /// 签约状态 /// </summary> public EnumWalletSignStatus SignStatus { get; set; } /// <summary> /// 错误代码 /// </summary> public string ErrorCode { get; set; } /// <summary> /// 返回具体的原因。 /// </summary> public string FailReason { get; set; } } } ApiTools.Core/Entities/Users/ChannelWalletTransaction.cs
New file @@ -0,0 +1,204 @@ using Furion.DatabaseAccessor; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包交易 /// </summary> public class ChannelWalletTransaction : CommonEntity<MasterDbContextLocator>, IEntityTypeBuilder<ChannelWalletTransaction> { /// <summary> /// 钱包Id /// </summary> public Guid WalletId { get; set; } /// <summary> /// 钱包 /// </summary> public ChannelWallet Wallet { get; set; } /// <summary> /// 平安信息 /// </summary> public ChannelWalletTransactionPingAnPay PingAnPay { get; set; } /// <summary> /// 类型 /// </summary> public EnumWalletTransactionType Type { get; set; } /// <summary> /// 订单号 /// </summary> public string Code { get; set; } /// <summary> /// 外部订单号 /// </summary> public string OutCode { get; set; } /// <summary> /// 并发锁 /// </summary> public string ConcurrencyLock { get; set; } /// <summary> /// 金额 /// </summary> public decimal Amount { get; set; } /// <summary> /// 余额 /// </summary> public decimal Balance { get; set; } /// <summary> /// 收支后余额 /// </summary> public decimal AfterBalance { get; set; } /// <summary> /// 外部操作人Id /// </summary> public string OutOperatorId { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime? OperatorTime { get; set; } /// <summary> /// 付款人账户 /// </summary> public string PayerAccount { get; set; } /// <summary> /// 付款人名称 /// </summary> public string PayerName { get; set; } /// <summary> /// 付款人开户行 /// </summary> public string PayerBank { get; set; } /// <summary> /// 付款人支行 /// </summary> public string PayerBankBranch { get; set; } /// <summary> /// 外部收款人Id /// </summary> public string OutReceiveId { get; set; } /// <summary> /// 收款人姓名 /// </summary> public string ReceiveName { get; set; } /// <summary> /// 收款人身份证号 /// </summary> public string ReceiveIdentity { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 收款人开户行 /// </summary> public string ReceiveBank { get; set; } /// <summary> /// 收款人支行 /// </summary> public string ReceiveBankBranch { get; set; } /// <summary> /// 币种 /// </summary> public string Currency { get; set; } /// <summary> /// 用途 /// </summary> public string Purpose { get; set; } /// <summary> /// 备注 /// </summary> public string Remark { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 /// </summary> public string ErrorCode { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 /// </summary> public string FailReason { get; set; } /// <summary> /// 订单支付时间 /// </summary> public DateTime? TransDate { get; set; } /// <summary> /// 预计收费金额(元),转账到银行卡专用 /// </summary> public decimal? OrderFee { get; set; } /// <summary> /// 电子收据Id /// </summary> public string EreceiptFileId { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadUrl { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadOssUrl { get; set; } /// <summary> /// 电子收据状态 /// </summary> public EnumWalletTransactionEreceiptStatus? EreceiptStatus { get; set; } /// <summary> /// 电子收据错误信息 /// </summary> public string EreceiptErrorMessage { get; set; } /// <summary> /// 状态 /// </summary> public EnumWalletTransactionStatus TransactionStatus { get; set; } public void Configure(EntityTypeBuilder<ChannelWalletTransaction> entityBuilder, DbContext dbContext, Type dbContextLocator) { entityBuilder .HasOne(it => it.PingAnPay) .WithOne(it => it.Transaction) .HasForeignKey<ChannelWalletTransactionPingAnPay>(it => it.Id); entityBuilder .HasIndex(it => it.ConcurrencyLock) .IsUnique(); } } } ApiTools.Core/Entities/Users/ChannelWalletTransactionPingAnPay.cs
New file @@ -0,0 +1,165 @@ using Furion.DatabaseAccessor; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包交易记录平安支付信息 /// </summary> public class ChannelWalletTransactionPingAnPay : CommonEntity<MasterDbContextLocator> { /// <summary> /// 交易 /// </summary> public ChannelWalletTransaction Transaction { get; set; } /// <summary> /// 止付编号 有效状态的平安易止付编号,从JGF001止付后返回的 /// </summary> public string FreezeNo { get; set; } /// <summary> /// 止付状态码 /// </summary> public string StopStt { get; set; } /// <summary> /// 止付失败原因 /// </summary> public string StopFailReason { get; set; } /// <summary> /// 解除止付状态码 /// </summary> public string RemoveStopStt { get; set; } /// <summary> /// 解除止付失败原因 /// </summary> public string RemoveStopFailReason { get; set; } /// <summary> /// 转账凭证号 /// </summary> public string ThirdVoucher { get; set; } /// <summary> /// 银行流水号 银行业务流水号;可以用于对账 /// </summary> public string FrontLogNo { get; set; } /// <summary> /// 客户自定义凭证号 用于客户转账登记和内部识别,通过转账结果查询可以返回。银行不检查唯一性 /// </summary> public string CstInnerFlowNo { get; set; } /// <summary> /// 转账退票标志 /// "0:未退票; 默认为0 /// 1:退票;" /// 数据长度:1,是否必输:N /// </summary> public string IsBack { get; set; } /// <summary> /// 支付失败或退票原因描述 /// "如果是超级网银则返回如下信息: /// RJ01对方返回:账号不存在 /// RJ02对方返回:账号、户名不符 /// 大小额支付则返回失败描述" /// 数据长度:20,是否必输:N /// </summary> public string BackRem { get; set; } /// <summary> /// 银行处理结果 /// "格式为:“六位代码:中文描述”。冒号为半角。如:000000:转账成功 /// 处理中的返回(以如下返回开头): /// MA9111:交易正在受理中 /// 000000:交易受理成功待处理 /// 000000:交易处理中 /// 000000:交易受理成功处理中 /// 成功的返回: /// 000000:转账交易成功 /// 其他的返回都为失败: /// MA9112:转账失败" /// 数据长度:40,是否必输:Y /// </summary> public string Yhcljg { get; set; } /// <summary> /// 转账加急标志 /// Y:加急 N:普通S:特急 /// 数据长度:1,是否必输:Y /// </summary> public string SysFlag { get; set; } /// <summary> /// 转账手续费 /// 数据长度:13,是否必输:Y /// </summary> public string Fee { get; set; } /// <summary> /// 转账代码类型 /// "4004:单笔转账; /// 4014:单笔批量; /// 4034:汇总批量" /// 数据长度:4,是否必输:Y /// </summary> public string TransBsn { get; set; } /// <summary> /// 交易受理时间 /// 交易受理时间 /// 数据长度:14,是否必输:N /// </summary> public string SubmitTime { get; set; } /// <summary> /// 记账日期 /// 主机记账日期 /// 数据长度:8,是否必输:N /// </summary> public string AccountDate { get; set; } /// <summary> /// 主机记账流水号 /// 主机记账流水 /// 数据长度:32,是否必输:N /// </summary> public string HostFlowNo { get; set; } /// <summary> /// 错误码 /// 交易失败的错误代码 /// 数据长度:20,是否必输:N /// </summary> public string HostErrorCode { get; set; } /// <summary> /// 代理人户名 /// 用于代理行支付功能 /// 数据长度:60,是否必输:N /// </summary> public string ProxyPayName { get; set; } /// <summary> /// 代理人账号 /// 用于代理行支付功能 /// 数据长度:30,是否必输:N /// </summary> public string ProxyPayAcc { get; set; } /// <summary> /// 代理人银行名称 /// 用于代理行支付功能 /// 数据长度:30,是否必输:N /// </summary> public string ProxyPayBankName { get; set; } } } ApiTools.Core/Enums/Resources/EnumResourceController.cs
@@ -53,6 +53,11 @@ [ResourceController(EnumResourceService.UserServer, "Channel")] UserServerChannel, /// <summary> /// 渠道钱包 /// </summary> [ResourceController(EnumResourceService.UserServer, "ChannelWallet")] UserServerChannelWallet, /// <summary> /// 渠道用户 /// </summary> [ResourceController(EnumResourceService.UserServer, "ChannelUser")] ApiTools.Core/Enums/Users/EnumWalletAccess.cs
New file @@ -0,0 +1,27 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包通道 /// </summary> public enum EnumWalletAccess { /// <summary> /// 支付宝 /// </summary> Alipay = 10, /// <summary> /// 平安银行 /// </summary> PingAnPay = 20, /// <summary> /// 微信 /// </summary> WeChatPay = 30, } } ApiTools.Core/Enums/Users/EnumWalletSignStatus.cs
New file @@ -0,0 +1,31 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包签约状态 /// </summary> public enum EnumWalletSignStatus { /// <summary> /// 未签约 /// </summary> Wait = 1, /// <summary> /// 申请中 /// </summary> Apply = 10, /// <summary> /// 已签约 /// </summary> Normal = 100, /// <summary> /// 终止 /// </summary> Stop = 999 } } ApiTools.Core/Enums/Users/EnumWalletTransactionEreceiptStatus.cs
New file @@ -0,0 +1,31 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 钱包交易电子收据状态 /// </summary> public enum EnumWalletTransactionEreceiptStatus { /// <summary> /// 初始化 /// </summary> INIT = 10, /// <summary> /// 处理中 /// </summary> PROCESS = 20, /// <summary> /// 成功 /// </summary> SUCCESS = 30, /// <summary> /// 失败 /// </summary> FAIL = 40, } } ApiTools.Core/Enums/Users/EnumWalletTransactionStatus.cs
New file @@ -0,0 +1,39 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 钱包交易状态 /// </summary> public enum EnumWalletTransactionStatus { /// <summary> /// 待提交 /// </summary> WaitSubmit = 1, /// <summary> /// 待支付 /// </summary> WaitPay = 10, /// <summary> /// 处理中 /// </summary> Dealing = 20, /// <summary> /// 成功 /// </summary> Success = 30, /// <summary> /// 退票 /// </summary> Refund = 40, /// <summary> /// 失败 /// </summary> Fail = 50, } } ApiTools.Core/Enums/Users/EnumWalletTransactionType.cs
New file @@ -0,0 +1,20 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { public enum EnumWalletTransactionType { /// <summary> /// 充值 /// </summary> Recharge = 10, /// <summary> /// 转账 /// </summary> Transfer = 20 } } ApiTools.Core/Jobs/RefreshChannelWalletTransactionStatusJob.cs
New file @@ -0,0 +1,58 @@ using Furion; using Furion.DatabaseAccessor; using Furion.EventBus; using Furion.Schedule; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 刷新渠道钱包交易状态 /// </summary> [JobDetail("RefreshChannelWalletTransactionStatusJob", Description = "刷新渠道钱包交易状态", Concurrent = false)] [PeriodMinutes(5)] public class RefreshChannelWalletTransactionStatusJob( ChannelWalletRepository channelWalletRepository, ChannelWalletTransactionRepository channelWalletTransactionRepository, ChannelWalletService channelWalletService ) : IJob { private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository; private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository; private readonly ChannelWalletService channelWalletService = channelWalletService; public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { var env = App.GetConfig<string>("Environment"); if (env != "Local") { var transactions = await channelWalletTransactionRepository.GetQueryable(false) .Where(it => it.TransactionStatus == EnumWalletTransactionStatus.WaitPay || it.TransactionStatus == EnumWalletTransactionStatus.Dealing) .ToListAsync(); var walletIds = transactions.DistinctSelect(it => it.WalletId); var wallets = await channelWalletRepository.GetQueryable(false) .Where(it => walletIds.Contains(it.Id)) .ToListAsync(); foreach (var transaction in transactions) { var wallet = wallets.FirstOrDefault(it => it.Id == transaction.WalletId); if (wallet != null) { // 查询交易详情 await channelWalletService.GetTransactionDetail(wallet, transaction); // 下载回单 await channelWalletService.DownloadEreceiptUrl(wallet, transaction); } } } } } } ApiTools.Core/Models/ChannelWallets/Commands/SaveChannelPingAnPayWalletCommand.cs
New file @@ -0,0 +1,45 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 保存渠道平安银行钱包 /// </summary> [Resource([EnumResourceController.UserServerChannelWallet])] public class SaveChannelPingAnPayWalletCommand : IRequest<SaveChannelPingAnPayWalletCommandResult> { /// <summary> /// 外部钱包Id /// </summary> public string OutWalletId { get; set; } /// <summary> /// 户名 /// </summary> public string Name { get; set; } /// <summary> /// 账号 /// </summary> public string Identity { get; set; } } public class SaveChannelPingAnPayWalletCommandResult { /// <summary> /// 钱包Id /// </summary> public Guid Id { get; set; } /// <summary> /// 余额 /// </summary> public decimal Balance { get; set; } } } ApiTools.Core/Models/ChannelWallets/Commands/SubmitChannelWalletTransferCommand.cs
New file @@ -0,0 +1,118 @@ using MediatR; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 提交渠道钱包转账 /// </summary> [Resource([EnumResourceController.UserServerChannelWallet])] public class SubmitChannelWalletTransferCommand : IRequest<SubmitChannelWalletTransferCommandResult> { /// <summary> /// 外部钱包Id /// </summary> public string OutWalletId { get; set; } /// <summary> /// 外部订单号 /// </summary> public string OutCode { get; set; } /// <summary> /// 外部操作人Id /// </summary> public string OutOperatorId { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime? OperatorTime { get; set; } /// <summary> /// 外部收款人Id /// </summary> public string OutReceiveId { get; set; } /// <summary> /// 金额 /// </summary> public decimal Amount { get; set; } /// <summary> /// 收款人姓名 /// </summary> public string ReceiveName { get; set; } /// <summary> /// 收款人身份证号 /// </summary> public string ReceiveIdentity { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 收款人开户行 /// </summary> public string ReceiveBank { get; set; } /// <summary> /// 收款人支行 /// </summary> public string ReceiveBankBranch { get; set; } /// <summary> /// 币种 /// </summary> public string Currency { get; set; } /// <summary> /// 用途 /// </summary> public string Purpose { get; set; } /// <summary> /// 备注 /// </summary> public string Remark { get; set; } } public class SubmitChannelWalletTransferCommandResult { /// <summary> /// 交易Id /// </summary> public Guid Id { get; set; } /// <summary> /// 订单号 /// </summary> public string Code { get; set; } /// <summary> /// 状态 /// </summary> public EnumWalletTransactionStatus TransactionStatus { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 /// </summary> public string ErrorCode { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 /// </summary> public string FailReason { get; set; } } } ApiTools.Core/Models/ChannelWallets/Queries/GetChannelPingAnPayWalletQuery.cs
New file @@ -0,0 +1,53 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 查询渠道平安银行钱包 /// </summary> [Resource([EnumResourceController.UserServerChannelWallet])] public class GetChannelPingAnPayWalletQuery : IRequest<GetChannelPingAnPayWalletQueryResult> { /// <summary> /// 外部钱包Id /// </summary> public string OutWalletId { get; set; } } /// <summary> /// 查询渠道平安银行钱包 /// </summary> public class GetChannelPingAnPayWalletQueryResult { /// <summary> /// 钱包Id /// </summary> public Guid Id { get; set; } /// <summary> /// 户名 /// </summary> public string Name { get; set; } /// <summary> /// 账号 /// </summary> public string Identity { get; set; } /// <summary> /// 余额 /// </summary> public decimal Balance { get; set; } /// <summary> /// 签约状态 /// </summary> public EnumWalletSignStatus SignStatus { get; set; } } } ApiTools.Core/Models/ChannelWallets/Queries/GetChannelWalletTransactionQuery.cs
New file @@ -0,0 +1,192 @@ using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 查询渠道钱包交易详情 /// </summary> [Resource([EnumResourceController.UserServerChannelWallet])] public class GetChannelWalletTransactionQuery : IRequest<GetChannelWalletTransactionQueryResult> { /// <summary> /// 外部订单号 /// </summary> public string OutCode { get; set; } } /// <summary> /// 查询渠道钱包交易详情 /// </summary> public class GetChannelWalletTransactionQueryResult { /// <summary> /// 交易Id /// </summary> public Guid Id { get; set; } /// <summary> /// 类型 /// </summary> public EnumWalletTransactionType Type { get; set; } /// <summary> /// 订单号 /// </summary> public string Code { get; set; } /// <summary> /// 外部订单号 /// </summary> public string OutCode { get; set; } /// <summary> /// 并发锁 /// </summary> public string ConcurrencyLock { get; set; } /// <summary> /// 金额 /// </summary> public decimal Amount { get; set; } /// <summary> /// 余额 /// </summary> public decimal Balance { get; set; } /// <summary> /// 收支后余额 /// </summary> public decimal AfterBalance { get; set; } /// <summary> /// 外部操作人Id /// </summary> public string OutOperatorId { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime? OperatorTime { get; set; } /// <summary> /// 付款人账户 /// </summary> public string PayerAccount { get; set; } /// <summary> /// 付款人名称 /// </summary> public string PayerName { get; set; } /// <summary> /// 付款人开户行 /// </summary> public string PayerBank { get; set; } /// <summary> /// 付款人支行 /// </summary> public string PayerBankBranch { get; set; } /// <summary> /// 外部收款人Id /// </summary> public string OutReceiveId { get; set; } /// <summary> /// 收款人姓名 /// </summary> public string ReceiveName { get; set; } /// <summary> /// 收款人身份证号 /// </summary> public string ReceiveIdentity { get; set; } /// <summary> /// 收款账户 /// </summary> public string ReceiveAccount { get; set; } /// <summary> /// 收款人开户行 /// </summary> public string ReceiveBank { get; set; } /// <summary> /// 收款人支行 /// </summary> public string ReceiveBankBranch { get; set; } /// <summary> /// 币种 /// </summary> public string Currency { get; set; } /// <summary> /// 用途 /// </summary> public string Purpose { get; set; } /// <summary> /// 备注 /// </summary> public string Remark { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回错误代码 /// </summary> public string ErrorCode { get; set; } /// <summary> /// 查询到的订单状态为FAIL失败或REFUND退票时,返回具体的原因。 /// </summary> public string FailReason { get; set; } /// <summary> /// 订单支付时间 /// </summary> public DateTime? TransDate { get; set; } /// <summary> /// 预计收费金额(元),转账到银行卡专用 /// </summary> public decimal? OrderFee { get; set; } /// <summary> /// 电子收据Id /// </summary> public string EreceiptFileId { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadUrl { get; set; } /// <summary> /// 电子收据下载链接 /// </summary> public string EreceiptDownloadOssUrl { get; set; } /// <summary> /// 电子收据状态 /// </summary> public EnumWalletTransactionEreceiptStatus? EreceiptStatus { get; set; } /// <summary> /// 电子收据错误信息 /// </summary> public string EreceiptErrorMessage { get; set; } /// <summary> /// 状态 /// </summary> public EnumWalletTransactionStatus TransactionStatus { get; set; } } } ApiTools.Core/Repositories/BaseRepository.cs
New file @@ -0,0 +1,351 @@ using EFCore.BulkExtensions; using Furion.DatabaseAccessor; using Furion.DistributedIDGenerator; using Furion.FriendlyException; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ApiTools.Core { public abstract class BaseRepository<TEntity, TDbContextLocator> where TEntity : CommonEntity, new() where TDbContextLocator : class, IDbContextLocator { public readonly IRepository<TEntity, TDbContextLocator> rep; public readonly CurrentLogier logier; public BaseRepository( IRepository<TEntity, TDbContextLocator> rep) { this.rep = rep; logier = JwtUtils.GetCurrentLogier(); } public virtual IQueryable<TEntity> GetQueryableIgnoreFilter(bool noTracking = true) { return rep.GetQueryable(noTracking); } /// <summary> /// 获取查询 /// </summary> /// <param name="noTracking"></param> /// <returns></returns> public virtual IQueryable<TEntity> GetQueryable(bool noTracking = true) { return rep.GetQueryable(noTracking); } /// <summary> /// 获取查询 /// </summary> /// <param name="noTracking"></param> /// <param name="query"></param> /// <returns></returns> public virtual IQueryable<TEntity> GetQueryable( bool noTracking, Func<IQueryable<TEntity>, IQueryable<TEntity>> query) { var q = GetQueryable(false); if (query != null) { q = query(q); } return q; } /// <summary> /// 获取实体 /// </summary> /// <param name="id"></param> /// <param name="query"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public virtual Task<TEntity> Get( Guid id, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) { return GetQueryable(false, query) .Where(it => it.Id == id) .FirstOrDefaultAsync(cancellationToken); } /// <summary> /// 获取实体 /// </summary> /// <param name="ids"></param> /// <param name="query"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public virtual Task<List<TEntity>> Get( List<Guid> ids, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) { return GetQueryable(false, query) .Where(it => ids.Contains(it.Id)) .ToListAsync(cancellationToken); } /// <summary> /// 查询选择器数据 /// </summary> /// <typeparam name="TValue"></typeparam> /// <typeparam name="TData"></typeparam> /// <param name="request"></param> /// <param name="getValue"></param> /// <param name="getLabel"></param> /// <param name="query"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<List<SelectOption<TValue, TData>>> GetSelect<TValue, TData>( SelectQuery<TValue, TData> request, Func<TData, TValue> getValue, Func<TData, string> getLabel, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) { var q = GetQueryable(); if (query != null) q = query(q); else q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime); var models = await q .ProjectToType<TData>() .ToListAsync(cancellationToken); var options = new List<SelectOption<TValue, TData>>(); foreach (var model in models) { var option = new SelectOption<TValue, TData>(); option.Data = model; option.Value = getValue(model); option.Label = getLabel(model); options.Add(option); } return options; } public async Task<TResult> GetDetail<TResult>( Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) { var model = await GetQueryable(false, query) .ProjectToType<TResult>() .FirstOrDefaultAsync(cancellationToken); if (model == null) { var summary = await typeof(TEntity).GetSummary(); throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "信息"}"); } return model; } /// <summary> /// 设置是否禁用 /// </summary> /// <param name="request"></param> /// <param name="query"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<int> SetIsDisabled( SetIsDisabledCommand request, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) { var q = GetQueryable(false); if (query != null) q = query(q); var entities = await q .Where(it => request.Ids.Contains(it.Id)) .ToListAsync(); var isDisabledProperty = typeof(TEntity).GetProperty("IsDisabled", typeof(bool)); foreach (var entity in entities) { isDisabledProperty.SetValue(entity, request.IsDisabled); } await UpdateAsync(entities); return entities.Count; } /// <summary> /// 删除数据 /// </summary> /// <param name="request"></param> /// <param name="query"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<int> DeleteData( DeleteDataCommand request, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) { var q = GetQueryable(false); if (query != null) q = query(q); var entities = await q .Where(it => request.Ids.Contains(it.Id)) .ToListAsync(cancellationToken); return entities.Any() ? await rep.DeleteNowAsync(entities, cancellationToken) : 0; } /// <summary> /// 更新数据 /// </summary> /// <typeparam name="TRequest"></typeparam> /// <param name="q"></param> /// <param name="request"></param> /// <param name="update"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<Guid> UpdateData<TRequest>( IQueryable<TEntity> q, TRequest request, Action<TEntity> update = null, CancellationToken cancellationToken = default) { var entity = await q.FirstOrDefaultAsync(); if (entity == null) { var summary = await typeof(TEntity).GetSummary(); throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "信息"}"); } if (update != null) update(entity); else request.Adapt(entity); await rep.UpdateAsync(entity); return entity.Id; } /// <summary> /// 保存数据 /// </summary> /// <typeparam name="TRequest"></typeparam> /// <param name="request"></param> /// <param name="query"></param> /// <param name="checkExist"></param> /// <param name="update"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<TEntity> SaveData<TRequest>( TRequest request, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, Expression<Func<TEntity, bool>> checkExist = null, Action<TEntity> update = null, CancellationToken cancellationToken = default) where TRequest : SaveDataCommand, new() { var xmlDoc = await XmlDocUtils.GetXmlDocAsync(); var summary = await typeof(TEntity).GetSummary(xmlDoc); if (checkExist != null && await GetQueryableIgnoreFilter().AnyAsync(checkExist)) throw Oops.Oh(EnumErrorCodeType.s405, $"{summary ?? "信息"}"); if (request.Id.HasValue) { var q = GetQueryable(false); if (query != null) q = query(q); var entity = await q.FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken); if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "信息"}"); if (update != null) update(entity); else request.Adapt(entity); await rep.UpdateAsync(entity); return entity; } else { var entity = new TEntity(); if (update != null) update(entity); else request.Adapt(entity); await rep.InsertAsync(entity); return entity; } } public virtual Task<List<T1>> SqlQueriesAsync<T1>(string sql, object model, CancellationToken cancellationToken = default) { return rep.SqlQueriesAsync<T1>(sql, model, cancellationToken); } public virtual IDbContextTransaction BeginTransaction() { return rep.Database.BeginTransaction(); } public virtual Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default) { return rep.InsertAsync(entity, cancellationToken: cancellationToken); } public virtual Task InsertNowAsync(TEntity entity, CancellationToken cancellationToken = default) { return rep.InsertNowAsync(entity, cancellationToken: cancellationToken); } public virtual Task InsertAsync(List<TEntity> entities, CancellationToken cancellationToken = default) { return rep.InsertAsync(entities, cancellationToken); } public virtual Task<int> InsertNowAsync(List<TEntity> entities, CancellationToken cancellationToken = default) { return rep.InsertNowAsync(entities, cancellationToken); } public virtual async Task BulkInsertAsync(List<TEntity> entities, CancellationToken cancellationToken = default) { await rep.Context.BulkInsertAsync(entities, cancellationToken: cancellationToken); } public virtual Task UpdateAsync(TEntity entity) { return rep.UpdateAsync(entity); } public virtual Task UpdateNowAsync(TEntity entity) { return rep.UpdateNowAsync(entity); } public virtual Task UpdateAsync(List<TEntity> entities) { return rep.UpdateAsync(entities); } public virtual Task<int> UpdateNowAsync(List<TEntity> entities) { return rep.UpdateNowAsync(entities); } public virtual Task DeleteAsync(TEntity entity) { return rep.DeleteAsync(entity); } public virtual Task DeleteNowAsync(TEntity entity, CancellationToken cancellationToken = default) { return rep.DeleteNowAsync(entity, cancellationToken); } public virtual Task DeleteAsync(List<TEntity> entities) { return rep.DeleteAsync(entities); } public virtual Task<int> DeleteNowAsync(List<TEntity> entities, CancellationToken cancellationToken = default) { return rep.DeleteNowAsync(entities, cancellationToken); } public virtual Task SaveNowAsync() { return rep.SaveNowAsync(); } } } ApiTools.Core/Repositories/ChannelWalletRepository.cs
New file @@ -0,0 +1,66 @@ using Furion.DatabaseAccessor; using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.FriendlyException; using Microsoft.EntityFrameworkCore; using pingan.openbank.api.sdk.enums; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 企业钱包仓库 /// </summary> public class ChannelWalletRepository : BaseRepository<ChannelWallet, MasterDbContextLocator>, IScoped { public ChannelWalletRepository(IRepository<ChannelWallet, MasterDbContextLocator> rep) : base(rep) { } public override IQueryable<ChannelWallet> GetQueryable(bool noTracking = true) { var q = rep.GetQueryable(noTracking); if (logier != null) { switch (logier.Type) { case EnumUserType.Channel: q = q.Where(it => it.ChannelId == logier.ChannelId); break; case EnumUserType.Operation: break; default: break; } } return q; } public Task<bool> CheckExist(string code, Guid? id) { return GetQueryableIgnoreFilter() .AnyAsync(it => it.Code == code && it.Id != id); } /// <summary> /// 设置编号 /// </summary> /// <param name="entity"></param> /// <returns></returns> public async Task SetCode(ChannelWallet entity) { entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; var exist = await CheckExist(entity.Code, entity.Id); if (exist) { await SetCode(entity); } } } } ApiTools.Core/Repositories/EnterpriseWalletTransactionRepository.cs
New file @@ -0,0 +1,41 @@ using Furion.DatabaseAccessor; using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { public class ChannelWalletTransactionRepository : BaseRepository<ChannelWalletTransaction, MasterDbContextLocator>, IScoped { public ChannelWalletTransactionRepository(IRepository<ChannelWalletTransaction, MasterDbContextLocator> rep) : base(rep) { } public Task<bool> CheckExist(string code, Guid? id) { return GetQueryableIgnoreFilter() .AnyAsync(it => it.Code == code && it.Id != id); } /// <summary> /// 设置编号 /// </summary> /// <param name="entity"></param> /// <returns></returns> public async Task SetCode(ChannelWalletTransaction entity) { entity.Code = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; var exist = await CheckExist(entity.Code, entity.Id); if (exist) { await SetCode(entity); } } } } ApiTools.Core/Services/ChannelPingAnPayWalletService.cs
New file @@ -0,0 +1,298 @@ using Aop.Api.Domain; using Furion.DatabaseAccessor; using Furion.DependencyInjection; using Furion.DistributedIDGenerator; using Furion.FriendlyException; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Identity.Client; using NetTopologySuite.Index.HPRtree; using Org.BouncyCastle.Ocsp; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection.Metadata; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { public class ChannelPingAnPayWalletService( ChannelWalletRepository channelWalletRepository, ChannelWalletTransactionRepository channelWalletTransactionRepository, PingAnPayUtils utils ) : IChannelWalletService, ITransient { private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository; private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository; private readonly PingAnPayUtils utils = utils; /// <summary> /// 查询企业钱包余额 /// </summary> /// <param name="wallet"></param> /// <returns></returns> public async Task<ChannelWallet> GetEnterpriseWalletBalance(ChannelWallet wallet) { if (wallet != null && wallet.Identity.IsNotNull()) { var response = await utils.CorAcctBalanceQuery(new CorAcctBalanceQueryRequest { Account = wallet.Identity, CcyCode = "RMB", }); if (response.Code.IsNotNull()) { wallet.Balance = 0; wallet.ErrorCode = response.Code; wallet.FailReason = response.Message; } else { wallet.ErrorCode = null; wallet.FailReason = null; wallet.SignStatus = EnumWalletSignStatus.Normal; wallet.Balance = response.AcctBalance.ToDecimal().Value; } } return wallet; } /// <summary> /// 转账 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> public async Task Transfer(ChannelWallet wallet, ChannelWalletTransaction transaction) { transaction.PingAnPay = new ChannelWalletTransactionPingAnPay(); var responseStop = await utils.StopPaymentAndSettlementAccounts(new StopPaymentAndSettlementAccountsRequest { CnsmrSeqNo = transaction.Code, AccountNo = transaction.PayerAccount, OpType = "A", CcyCode = "RMB", SeqNo = $"{DateTime.Now:yyyyMMddHHmmssfff}{new Random(IDGen.NextID().GetHashCode()).Next(100, 999)}", TradeDate = DateTime.Now.ToString("yyyyMMdd").ToInt()!.Value, TradeTime = DateTime.Now.ToString("HHmmss").ToInt()!.Value, }); if (responseStop.Code.IsNotNull()) { transaction.ErrorCode = responseStop.Code; transaction.FailReason = responseStop.Errors?.FirstOrDefault()?.ErrorMessage ?? responseStop.Message; transaction.PingAnPay.StopStt = "30"; transaction.PingAnPay.StopFailReason = transaction.FailReason; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else { if (responseStop.StopPayFlw.IsNotNull() && responseStop.Stt == "20") { transaction.PingAnPay.FreezeNo = responseStop.StopPayFlw; } else { var responseStopDetail = await utils.InquiryAccountStopPaymentDetails(new InquiryAccountStopPaymentDetailsRequest { CnsmrSeqNo = transaction.Code, AccountNo = transaction.PayerAccount, PageNo = "1", }); if (responseStopDetail.Code.IsNotNull()) { transaction.ErrorCode = responseStopDetail.Code; transaction.FailReason = responseStopDetail.Errors?.FirstOrDefault()?.ErrorMessage ?? responseStopDetail.Message; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else if (responseStopDetail.List.IsNotNull()) { transaction.PingAnPay.FreezeNo = responseStopDetail.List.FirstOrDefault(it => it.FreezeStatu == "0")?.StopPayFlw; } else { transaction.FailReason = "止付失败并未查询到止付编号"; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } } } if (transaction.PingAnPay.FreezeNo.IsNotNull()) { transaction.PingAnPay.ThirdVoucher = transaction.Code; await channelWalletTransactionRepository.UpdateNowAsync(transaction); var responsePayment = await utils.SingleApplicationSuspensionPayment(new SingleApplicationSuspensionPaymentRequest { CcyCode = "RMB", CnsmrSeqNo = transaction.Code, FreezeNo = transaction.PingAnPay.FreezeNo, ThirdVoucher = transaction.Code, OutAcctName = wallet.Name, OutAcctNo = wallet.Identity, InAcctBankName = transaction.ReceiveBank, InAcctName = transaction.ReceiveName, InAcctNo = transaction.ReceiveAccount, TranAmount = transaction.Amount.ToString(), UseEx = transaction.Purpose, UnionFlag = wallet.Bank == transaction.ReceiveBank ? "1" : "0", AddrFlag = "1" }); if (responsePayment.Code.IsNotNull()) { transaction.ErrorCode = responsePayment.Code; transaction.FailReason = responsePayment.Errors?.FirstOrDefault()?.ErrorMessage ?? responsePayment.Message; transaction.TransactionStatus = EnumWalletTransactionStatus.Fail; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else { await GetTransactionDetail(wallet, transaction); if (transaction.TransactionStatus == EnumWalletTransactionStatus.Success) { await DownloadEreceiptUrl(wallet, transaction); } } } } /// <summary> /// 查询交易记录 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> public async Task GetTransactionDetail(ChannelWallet wallet, ChannelWalletTransaction transaction) { var response = await utils.CorSingleTransferQuery(new CorSingleTransferQueryRequest { OrigThirdVoucher = transaction.Code, }); if (response.Code.IsNotNull()) { transaction.ErrorCode = response.Code; transaction.FailReason = response.Errors?.FirstOrDefault()?.ErrorMessage ?? response.Message; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else { response.Adapt(transaction.PingAnPay); transaction.TransDate = response.AccountDate.ToDateTime(); transaction.OrderFee = response.Fee.ToDecimal(); transaction.TransactionStatus = response.Stt == "20" ? EnumWalletTransactionStatus.Success : response.Stt == "30" ? EnumWalletTransactionStatus.Fail : EnumWalletTransactionStatus.Dealing; if (transaction.TransactionStatus == EnumWalletTransactionStatus.Fail) { transaction.ErrorCode = response.Stt; transaction.FailReason = response.BackRem; } else { transaction.ErrorCode = null; transaction.FailReason = null; } if (transaction.TransactionStatus == EnumWalletTransactionStatus.Success && transaction.TransDate == null) { transaction.TransDate = DateTime.Now; } await channelWalletTransactionRepository.UpdateNowAsync(transaction); if (transaction.TransactionStatus != EnumWalletTransactionStatus.Dealing) { var responseStop = await utils.StopPaymentAndSettlementAccounts(new StopPaymentAndSettlementAccountsRequest { CnsmrSeqNo = transaction.Code, AccountNo = transaction.PayerAccount, StopPayFlw = transaction.PingAnPay.FreezeNo, OpType = "D", CcyCode = "RMB", SeqNo = $"{DateTime.Now:yyyyMMddHHmmssfff}{new Random(IDGen.NextID().GetHashCode()).Next(100, 999)}", TradeDate = DateTime.Now.ToString("yyyyMMdd").ToInt()!.Value, TradeTime = DateTime.Now.ToString("HHmmss").ToInt()!.Value, }); if (responseStop.Code.IsNotNull()) { transaction.PingAnPay.RemoveStopStt = "30"; transaction.PingAnPay.RemoveStopFailReason = responseStop.Errors?.FirstOrDefault()?.ErrorMessage ?? responseStop.Message; } else { transaction.PingAnPay.RemoveStopStt = responseStop.Stt; transaction.PingAnPay.RemoveStopFailReason = responseStop.SttDesc; } await channelWalletTransactionRepository.UpdateNowAsync(transaction); } } } /// <summary> /// 下载电子收据 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> public async Task DownloadEreceiptUrl(ChannelWallet wallet, ChannelWalletTransaction transaction) { var response = await utils.SameDayHistoryReceiptDataQuery(new SameDayHistoryReceiptDataQueryRequest { OutAccNo = transaction.PayerAccount, AccountBeginDate = transaction.PingAnPay.AccountDate, AccountEndDate = transaction.PingAnPay.AccountDate, InAccNo = transaction.ReceiveAccount, HostFlow = transaction.PingAnPay.HostFlowNo }); if (response.Code.IsNotNull()) { transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.FAIL; transaction.EreceiptErrorMessage = response.Errors?.FirstOrDefault()?.ErrorMessage ?? response.Message; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else if (response.List.IsNull()) { transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.FAIL; transaction.EreceiptErrorMessage = "未找到回单记录"; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else { var responseDownload = await utils.SingleOrBatchReceiptPDFMergeDownloadNew(new SingleOrBatchReceiptPDFMergeDownloadNewRequest { OutAccNo = transaction.PayerAccount, List = response.List .Select(it => new SingleOrBatchReceiptPDFMergeDownloadNewRequestItem { RecepitType = it.ReceiptType, SeqNo = it.SeqNo, AccountDate = it.AccountDate }) .ToList() }); if (responseDownload.Code.IsNotNull()) { transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.FAIL; transaction.EreceiptErrorMessage = responseDownload.Errors?.FirstOrDefault()?.ErrorMessage ?? responseDownload.Message; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } else { transaction.EreceiptFileId = responseDownload.DocID; transaction.EreceiptDownloadUrl = utils.DownloadFile(responseDownload.DocID, responseDownload.FileName); transaction.EreceiptDownloadOssUrl = AliyunOSSUtils.Upload( "PingAnPay", new MemoryStream(File.ReadAllBytes(transaction.EreceiptDownloadUrl)), $"电子回单-{transaction.Code}.zip") .Url; transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.SUCCESS; await channelWalletTransactionRepository.UpdateNowAsync(transaction); } } } } } ApiTools.Core/Services/ChannelWalletService.cs
New file @@ -0,0 +1,109 @@ using Aop.Api.Domain; using Furion.DatabaseAccessor; using Furion.DependencyInjection; using Furion.FriendlyException; using Microsoft.EntityFrameworkCore; using pingan.openbank.api.sdk.enums; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包服务 /// </summary> /// <param name="channelWalletRepository"></param> /// <param name="channelPingAnPayWalletService"></param> public class ChannelWalletService( ChannelWalletRepository channelWalletRepository, ChannelPingAnPayWalletService channelPingAnPayWalletService ) : ITransient { private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository; private readonly ChannelPingAnPayWalletService channelPingAnPayWalletService = channelPingAnPayWalletService; public IChannelWalletService GetService(EnumWalletAccess access) { switch (access) { //case EnumWalletAccess.Alipay: // return enterpriseAliPayWalletService; case EnumWalletAccess.PingAnPay: return channelPingAnPayWalletService; //case EnumWalletAccess.WeChatPay: // return enterpriseWeChatPayWalletService; default: throw Oops.Oh(EnumErrorCodeType.s400, "支付通道不支持"); } } /// <summary> /// 查询企业钱包余额 /// </summary> /// <param name="outWalletId"></param> /// <returns></returns> public async Task<ChannelWallet> GetEnterpriseWallet(string outWalletId) { var logier = JwtUtils.GetCurrentLogier(); var wallet = await channelWalletRepository.GetQueryable(false) .Where(it => it.ChannelId == logier.ChannelId && it.OutWalletId == outWalletId) .FirstOrDefaultAsync(); return await GetService(wallet.Access).GetEnterpriseWalletBalance(wallet); } /// <summary> /// 查询企业钱包余额 /// </summary> /// <param name="wallet"></param> /// <returns></returns> public async Task<ChannelWallet> GetEnterpriseWalletBalance(ChannelWallet wallet) { return await GetService(wallet.Access).GetEnterpriseWalletBalance(wallet); } /// <summary> /// 转账 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> public async Task Transfer(ChannelWallet wallet, ChannelWalletTransaction transaction) { await GetService(wallet.Access).Transfer(wallet, transaction); } /// <summary> /// 查询交易记录 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> public async Task GetTransactionDetail(ChannelWallet wallet, ChannelWalletTransaction transaction) { await GetService(wallet.Access).GetTransactionDetail(wallet, transaction); } /// <summary> /// 下载电子收据 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> public async Task DownloadEreceiptUrl(ChannelWallet wallet, ChannelWalletTransaction transaction) { if (transaction.TransactionStatus == EnumWalletTransactionStatus.Success) { await GetService(wallet.Access).DownloadEreceiptUrl(wallet, transaction); } } public string GetLockKey(Guid channelId, string outWalletId) { return $"EnterpriseWallet:{channelId}:{outWalletId}"; } } } ApiTools.Core/Services/IChannelWalletService.cs
New file @@ -0,0 +1,45 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { /// <summary> /// 渠道钱包服务 /// </summary> public interface IChannelWalletService { /// <summary> /// 查询渠道钱包余额 /// </summary> /// <param name="wallet"></param> /// <returns></returns> Task<ChannelWallet> GetEnterpriseWalletBalance(ChannelWallet wallet); /// <summary> /// 转账 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> Task Transfer(ChannelWallet wallet, ChannelWalletTransaction transaction); /// <summary> /// 查询交易记录 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> Task GetTransactionDetail(ChannelWallet wallet, ChannelWalletTransaction transaction); /// <summary> /// 下载电子收据 /// </summary> /// <param name="wallet"></param> /// <param name="transaction"></param> /// <returns></returns> Task DownloadEreceiptUrl(ChannelWallet wallet, ChannelWalletTransaction transaction); } } ApiTools.Core/Utils/CollectionUtils/CollectionUtils.cs
@@ -1,4 +1,6 @@ using System; using Furion.DatabaseAccessor; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -69,5 +71,28 @@ { return !list.IsNull(); } public static IQueryable<TEntity> GetQueryable<TEntity, TDbContextLocator>(this IRepository<TEntity, TDbContextLocator> rep, bool noTracking = true) where TEntity : class, IPrivateEntity, new() where TDbContextLocator : class, IDbContextLocator { var q = rep.AsQueryable(); if (noTracking) { q = q.AsNoTracking(); } return q; } public static IQueryable<TEntity> GetQueryable<TEntity>(this IRepository<TEntity> rep, bool noTracking = true) where TEntity : class, IPrivateEntity, new() { var q = rep.AsQueryable(); if (noTracking) { q = q.AsNoTracking(); } return q; } } } ApiTools.Core/Utils/DistributedCacheUtils/DistributedLock.cs
New file @@ -0,0 +1,20 @@ using Medallion.Threading; using Medallion.Threading.Redis; using System; using System.Threading; using System.Threading.Tasks; namespace ApiTools.Core { public static class DistributedLock { public static ValueTask<IDistributedSynchronizationHandle> TryAcquireAsync( this IDistributedLockProvider provider, string lockKey, TimeSpan timeout, CancellationToken cancellationToken = default) { lockKey = $"DistributedLock:{lockKey}"; var @lock = provider.CreateLock(lockKey); return @lock.TryAcquireAsync(timeout, cancellationToken); } } } ApiTools.Core/Utils/DistributedCacheUtils/DistributedLockServiceComponent.cs
New file @@ -0,0 +1,24 @@ using Furion; using Medallion.Threading; using Medallion.Threading.Redis; using Microsoft.Extensions.DependencyInjection; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ApiTools.Core { public sealed class DistributedLockServiceComponent : IServiceComponent { public void Load(IServiceCollection services, ComponentContext componentContext) { var configuration = App.GetConfig<string>("DistributedCache:Configuration"); var connection = ConnectionMultiplexer.Connect(configuration); var database = connection.GetDatabase(); services.AddSingleton<IDistributedLockProvider>(it => new RedisDistributedSynchronizationProvider(database)); } } } ApiTools.Core/Utils/PingAnPayUtils/Models/HistoryBalanceQueryRequest.cs
File was deleted ApiTools.Core/Utils/PingAnPayUtils/Models/InquiryAccountDayHistoryTransactionDetailsRequest.cs
File was deleted ApiTools.Core/Utils/PingAnPayUtils/Models/SingleDataQueryRequest.cs
File was deleted ApiTools.Core/Utils/PingAnPayUtils/PingAnPayUtils.cs
@@ -51,26 +51,6 @@ } /// <summary> /// 历史余额查询_银企直联 /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task<HistoryBalanceQueryResponse> HistoryBalanceQuery(HistoryBalanceQueryRequest request) { return await Send<HistoryBalanceQueryRequest, HistoryBalanceQueryResponse>(request, "/V1.0/bedl/HistoryBalanceQuery"); } /// <summary> /// 查询账户当日历史交易明细_银企直联 /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task<InquiryAccountDayHistoryTransactionDetailsResponse> InquiryAccountDayHistoryTransactionDetails(InquiryAccountDayHistoryTransactionDetailsRequest request) { return await Send<InquiryAccountDayHistoryTransactionDetailsRequest, InquiryAccountDayHistoryTransactionDetailsResponse>(request, "/V1.0/bedl/InquiryAccountDayHistoryTransactionDetails"); } /// <summary> /// 账户止付和解止付_银企直联 对公账户层的止付、解除止付 /// </summary> /// <param name="request"></param> @@ -108,16 +88,6 @@ public async Task<CorSingleTransferQueryResponse> CorSingleTransferQuery(CorSingleTransferQueryRequest request) { return await Send<CorSingleTransferQueryRequest, CorSingleTransferQueryResponse>(request, "/V1.0/bedl/CorSingleTransferQuery"); } /// <summary> /// 当日历史回单数据查询接口_银企直联 /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task<SingleDataQueryResponse> SingleDataQuery(SingleDataQueryRequest request) { return await Send<SingleDataQueryRequest, SingleDataQueryResponse>(request, "/V1.0/bedl/SingleDataQuery"); } /// <summary> ApiTools.Core/Utils/ScheduleUtils/DbJobPersistence.cs
@@ -16,21 +16,13 @@ /// <summary> /// 作业持久化(数据库) /// </summary> public class DbJobPersistence : IJobPersistence, IDisposable public class DbJobPersistence : IJobPersistence { private readonly IServiceScope _serviceScope; private readonly IRepository<ScheduleJobDetail> repScheduleJobDetail; private readonly IRepository<ScheduleJobTrigger> repScheduleJobTrigger; private readonly IRepository<ScheduleJobTriggerTimeline, LogDbContextLocator> repScheduleJobTriggerTimeline; private readonly IServiceScopeFactory serviceScopeFactory; public DbJobPersistence(IServiceScopeFactory scopeFactory) public DbJobPersistence(IServiceScopeFactory serviceScopeFactory) { _serviceScope = scopeFactory.CreateScope(); var services = _serviceScope.ServiceProvider; repScheduleJobDetail = services.GetService<IRepository<ScheduleJobDetail>>(); repScheduleJobTrigger = services.GetService<IRepository<ScheduleJobTrigger>>(); repScheduleJobTriggerTimeline = services.GetService<IRepository<ScheduleJobTriggerTimeline, LogDbContextLocator>>(); this.serviceScopeFactory = serviceScopeFactory; } /// <summary> @@ -44,78 +36,28 @@ public Task<SchedulerBuilder> OnLoadingAsync(SchedulerBuilder builder, CancellationToken stoppingToken) { // 标记从其他地方更新,比如数据库 return Task.FromResult(builder); } public async Task OnChangedAsync(PersistenceContext context) public Task OnChangedAsync(PersistenceContext context) { switch (context.Behavior) { case PersistenceBehavior.Appended: var insertEntity = new ScheduleJobDetail(); context.JobDetail.Adapt(insertEntity); await repScheduleJobDetail.InsertNowAsync(insertEntity); break; case PersistenceBehavior.Updated: var updateEntity = await repScheduleJobDetail.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId); if (updateEntity != null) { context.JobDetail.Adapt(updateEntity); await repScheduleJobDetail.UpdateNowAsync(updateEntity); } break; case PersistenceBehavior.Removed: var deleteEntity = await repScheduleJobDetail.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId); if (deleteEntity != null) { await repScheduleJobDetail.DeleteNowAsync(deleteEntity); } break; default: break; } return Task.CompletedTask; } public async Task OnTriggerChangedAsync(PersistenceTriggerContext context) public Task OnTriggerChangedAsync(PersistenceTriggerContext context) { switch (context.Behavior) { case PersistenceBehavior.Appended: var insertEntity = new ScheduleJobTrigger(); context.Trigger.Adapt(insertEntity); await repScheduleJobTrigger.InsertNowAsync(insertEntity); break; case PersistenceBehavior.Updated: var updateEntity = await repScheduleJobTrigger.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId && it.TriggerId == context.TriggerId); if (updateEntity != null) { context.Trigger.Adapt(updateEntity); await repScheduleJobTrigger.UpdateNowAsync(updateEntity); } break; case PersistenceBehavior.Removed: var deleteEntity = await repScheduleJobTrigger.AsQueryable().FirstOrDefaultAsync(it => it.JobId == context.JobId && it.TriggerId == context.TriggerId); if (deleteEntity != null) { await repScheduleJobTrigger.DeleteNowAsync(deleteEntity); } break; default: break; } return Task.CompletedTask; } public async Task OnExecutionRecordAsync(PersistenceExecutionRecordContext context) { var entity = new ScheduleJobTriggerTimeline(); context.Timeline.Adapt(entity); await repScheduleJobTriggerTimeline.InsertNowAsync(entity); } public void Dispose() { _serviceScope?.Dispose(); using (var scope = serviceScopeFactory.CreateScope()) { var rep = scope.ServiceProvider.GetRequiredService<IRepository<ScheduleJobTriggerTimeline, LogDbContextLocator>>(); var entity = new ScheduleJobTriggerTimeline(); context.Timeline.Adapt(entity); await rep.InsertNowAsync(entity); } } } } ApiTools.Database.Migrations/Migrations/20251119014221_UpdateChannelWallet1119.Designer.cs
New file @@ -0,0 +1,998 @@ // <auto-generated /> using System; using ApiTools.EntityFramework.Core; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; #nullable disable namespace ApiTools.Database.Migrations.Migrations { [DbContext(typeof(DefaultDbContext))] [Migration("20251119014221_UpdateChannelWallet1119")] partial class UpdateChannelWallet1119 { /// <inheritdoc /> protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "9.0.2") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); modelBuilder.Entity("ApiTools.Core.Channel", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("Code") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<bool>("IsDisabled") .HasColumnType("bit"); b.Property<string>("Name") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.ToTable("Channel"); }); modelBuilder.Entity("ApiTools.Core.ChannelWallet", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<int>("Access") .HasColumnType("int"); b.Property<decimal>("Balance") .HasColumnType("decimal(18,2)"); b.Property<string>("Bank") .HasColumnType("nvarchar(max)"); b.Property<string>("BankBranch") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("ChannelId") .HasColumnType("uniqueidentifier"); b.Property<string>("Code") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("ErrorCode") .HasColumnType("nvarchar(max)"); b.Property<string>("FailReason") .HasColumnType("nvarchar(max)"); b.Property<string>("Identity") .HasColumnType("nvarchar(max)"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<string>("Name") .HasColumnType("nvarchar(max)"); b.Property<string>("OutWalletId") .HasColumnType("nvarchar(max)"); b.Property<int>("SignStatus") .HasColumnType("int"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.HasIndex("ChannelId"); b.ToTable("ChannelWallet"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<decimal>("AfterBalance") .HasColumnType("decimal(18,2)"); b.Property<decimal>("Amount") .HasColumnType("decimal(18,2)"); b.Property<decimal>("Balance") .HasColumnType("decimal(18,2)"); b.Property<string>("Code") .HasColumnType("nvarchar(max)"); b.Property<string>("ConcurrencyLock") .HasColumnType("nvarchar(450)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("Currency") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptDownloadOssUrl") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptDownloadUrl") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptErrorMessage") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptFileId") .HasColumnType("nvarchar(max)"); b.Property<int?>("EreceiptStatus") .HasColumnType("int"); b.Property<string>("ErrorCode") .HasColumnType("nvarchar(max)"); b.Property<string>("FailReason") .HasColumnType("nvarchar(max)"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<DateTime?>("OperatorTime") .HasColumnType("datetime2"); b.Property<decimal?>("OrderFee") .HasColumnType("decimal(18,2)"); b.Property<string>("OutCode") .HasColumnType("nvarchar(max)"); b.Property<string>("OutOperatorId") .HasColumnType("nvarchar(max)"); b.Property<string>("OutReceiveId") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerAccount") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerBank") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerBankBranch") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerName") .HasColumnType("nvarchar(max)"); b.Property<string>("Purpose") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveAccount") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveBank") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveBankBranch") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveIdentity") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveName") .HasColumnType("nvarchar(max)"); b.Property<string>("Remark") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTime?>("TransDate") .HasColumnType("datetime2"); b.Property<int>("TransactionStatus") .HasColumnType("int"); b.Property<int>("Type") .HasColumnType("int"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.Property<Guid>("WalletId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.HasIndex("ConcurrencyLock") .IsUnique() .HasFilter("[ConcurrencyLock] IS NOT NULL"); b.HasIndex("WalletId"); b.ToTable("ChannelWalletTransaction"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("AccountDate") .HasColumnType("nvarchar(max)"); b.Property<string>("BackRem") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("CstInnerFlowNo") .HasColumnType("nvarchar(max)"); b.Property<string>("Fee") .HasColumnType("nvarchar(max)"); b.Property<string>("FreezeNo") .HasColumnType("nvarchar(max)"); b.Property<string>("FrontLogNo") .HasColumnType("nvarchar(max)"); b.Property<string>("HostErrorCode") .HasColumnType("nvarchar(max)"); b.Property<string>("HostFlowNo") .HasColumnType("nvarchar(max)"); b.Property<string>("IsBack") .HasColumnType("nvarchar(max)"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<string>("ProxyPayAcc") .HasColumnType("nvarchar(max)"); b.Property<string>("ProxyPayBankName") .HasColumnType("nvarchar(max)"); b.Property<string>("ProxyPayName") .HasColumnType("nvarchar(max)"); b.Property<string>("RemoveStopFailReason") .HasColumnType("nvarchar(max)"); b.Property<string>("RemoveStopStt") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("StopFailReason") .HasColumnType("nvarchar(max)"); b.Property<string>("StopStt") .HasColumnType("nvarchar(max)"); b.Property<string>("SubmitTime") .HasColumnType("nvarchar(max)"); b.Property<string>("SysFlag") .HasColumnType("nvarchar(max)"); b.Property<string>("ThirdVoucher") .HasColumnType("nvarchar(max)"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<string>("TransBsn") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("Yhcljg") .HasColumnType("nvarchar(max)"); b.HasKey("Id"); b.ToTable("ChannelWalletTransactionPingAnPay"); }); modelBuilder.Entity("ApiTools.Core.Resource", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("ActionName") .HasColumnType("nvarchar(max)"); b.Property<string>("ActionSummary") .HasColumnType("nvarchar(max)"); b.Property<bool>("AllowAnonymous") .HasColumnType("bit"); b.Property<string>("ApplicationName") .HasColumnType("nvarchar(max)"); b.Property<string>("Code") .IsRequired() .HasColumnType("nvarchar(max)"); b.Property<string>("ControllerName") .HasColumnType("nvarchar(max)"); b.Property<string>("ControllerSummary") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<bool>("CustomResponse") .HasColumnType("bit"); b.Property<string>("DynamicAssemblyName") .HasColumnType("nvarchar(max)"); b.Property<bool>("FileUpload") .HasColumnType("bit"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<bool>("IsExpired") .HasColumnType("bit"); b.Property<bool>("IsFromForm") .HasColumnType("bit"); b.Property<int>("Method") .HasColumnType("int"); b.Property<string>("Name") .IsRequired() .HasColumnType("nvarchar(max)"); b.Property<string>("RequestTypeFullName") .IsRequired() .HasColumnType("nvarchar(max)"); b.Property<string>("RequestTypeName") .IsRequired() .HasColumnType("nvarchar(max)"); b.Property<string>("ResponseTypeFullName") .HasColumnType("nvarchar(max)"); b.Property<string>("ResponseTypeName") .HasColumnType("nvarchar(max)"); b.Property<string>("Route") .IsRequired() .HasColumnType("nvarchar(max)"); b.Property<string>("RouteArea") .HasColumnType("nvarchar(max)"); b.Property<string>("ServiceName") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.ToTable("Resource"); }); modelBuilder.Entity("ApiTools.Core.ScheduleJobDetail", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("AssemblyName") .HasColumnType("nvarchar(max)"); b.Property<bool>("Concurrent") .HasColumnType("bit"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("Description") .HasColumnType("nvarchar(max)"); b.Property<string>("GroupName") .HasColumnType("nvarchar(max)"); b.Property<bool>("IncludeAnnotations") .HasColumnType("bit"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<string>("JobId") .HasColumnType("nvarchar(max)"); b.Property<string>("JobType") .HasColumnType("nvarchar(max)"); b.Property<string>("Properties") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.ToTable("ScheduleJobDetail"); }); modelBuilder.Entity("ApiTools.Core.ScheduleJobTrigger", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("Args") .HasColumnType("nvarchar(max)"); b.Property<string>("AssemblyName") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("Description") .HasColumnType("nvarchar(max)"); b.Property<long>("ElapsedTime") .HasColumnType("bigint"); b.Property<DateTime?>("EndTime") .HasColumnType("datetime2"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<string>("JobId") .HasColumnType("nvarchar(max)"); b.Property<DateTime?>("LastRunTime") .HasColumnType("datetime2"); b.Property<long>("MaxNumberOfErrors") .HasColumnType("bigint"); b.Property<long>("MaxNumberOfRuns") .HasColumnType("bigint"); b.Property<DateTime?>("NextRunTime") .HasColumnType("datetime2"); b.Property<long>("NumRetries") .HasColumnType("bigint"); b.Property<long>("NumberOfErrors") .HasColumnType("bigint"); b.Property<long>("NumberOfRuns") .HasColumnType("bigint"); b.Property<bool>("ResetOnlyOnce") .HasColumnType("bit"); b.Property<string>("Result") .HasColumnType("nvarchar(max)"); b.Property<int>("RetryTimeout") .HasColumnType("int"); b.Property<bool>("RunOnStart") .HasColumnType("bit"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<bool>("StartNow") .HasColumnType("bit"); b.Property<DateTime?>("StartTime") .HasColumnType("datetime2"); b.Property<long>("Status") .HasColumnType("bigint"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<string>("TriggerId") .HasColumnType("nvarchar(max)"); b.Property<string>("TriggerType") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.ToTable("ScheduleJobTrigger"); }); modelBuilder.Entity("ApiTools.Core.SmsLog", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<int>("Access") .HasColumnType("int"); b.Property<Guid?>("ChannelCreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<Guid?>("ChannelId") .HasColumnType("uniqueidentifier"); b.Property<string>("Code") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<DateTime?>("Expiry") .HasColumnType("datetime2"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<bool>("IsUsed") .HasColumnType("bit"); b.Property<string>("Message") .HasColumnType("nvarchar(max)"); b.Property<string>("PhoneNumber") .IsRequired() .HasMaxLength(11) .HasColumnType("nvarchar(11)"); b.Property<string>("RequestId") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<int>("Status") .HasColumnType("int"); b.Property<string>("TemplateCode") .IsRequired() .HasMaxLength(128) .HasColumnType("nvarchar(128)"); b.Property<string>("TemplateParam") .HasColumnType("nvarchar(max)"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.HasIndex("ChannelId"); b.ToTable("SmsLog"); }); modelBuilder.Entity("ApiTools.Core.SmsSetting", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<Guid?>("ChannelId") .HasColumnType("uniqueidentifier"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<int>("DailyMaxCount") .HasColumnType("int"); b.Property<int>("HourlyMaxCount") .HasColumnType("int"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<bool>("IsDisabled") .HasColumnType("bit"); b.Property<int>("MinutelyMaxCount") .HasColumnType("int"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.Property<bool>("WithoutParams") .HasColumnType("bit"); b.HasKey("Id"); b.HasIndex("ChannelId"); b.ToTable("SmsSetting"); }); modelBuilder.Entity("ApiTools.Core.SmsSettingAccess", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<int>("Access") .HasColumnType("int"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<bool>("IsDisabled") .HasColumnType("bit"); b.Property<Guid>("SettingId") .HasColumnType("uniqueidentifier"); b.Property<string>("SignName") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.HasIndex("SettingId"); b.ToTable("SmsSettingAccess"); }); modelBuilder.Entity("ApiTools.Core.User", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("Avatar") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("ChannelId") .HasColumnType("uniqueidentifier"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<bool>("IsCheckPhoneNumber") .HasColumnType("bit"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<int>("Level") .HasColumnType("int"); b.Property<string>("Name") .HasMaxLength(32) .HasColumnType("nvarchar(32)"); b.Property<string>("Password") .HasColumnType("nvarchar(max)"); b.Property<string>("PhoneNumber") .HasMaxLength(11) .HasColumnType("nvarchar(11)"); b.Property<string>("Remark") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<int>("Status") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<int>("Type") .HasColumnType("int"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("UserName") .IsRequired() .HasMaxLength(32) .HasColumnType("nvarchar(32)"); b.HasKey("Id"); b.HasIndex("ChannelId"); b.ToTable("User"); b.HasData( new { Id = new Guid("11111111-1111-1111-1111-111111111111"), CreatedTime = new DateTimeOffset(new DateTime(2000, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 8, 0, 0, 0)), IsCheckPhoneNumber = false, IsDeleted = false, Level = 999, Name = "管理员", Password = "iEYggKrMhQ3ASUGLobra1w==:fn/DsMJUbD9FGpvBvR3moMpMPptdxzZlourPVhU479I=", Sort = 0, Status = 10, Type = 100, UserName = "system" }); }); modelBuilder.Entity("ApiTools.Core.ChannelWallet", b => { b.HasOne("ApiTools.Core.Channel", "Channel") .WithMany() .HasForeignKey("ChannelId"); b.Navigation("Channel"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b => { b.HasOne("ApiTools.Core.ChannelWallet", "Wallet") .WithMany() .HasForeignKey("WalletId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Wallet"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b => { b.HasOne("ApiTools.Core.ChannelWalletTransaction", "Transaction") .WithOne("PingAnPay") .HasForeignKey("ApiTools.Core.ChannelWalletTransactionPingAnPay", "Id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Transaction"); }); modelBuilder.Entity("ApiTools.Core.SmsLog", b => { b.HasOne("ApiTools.Core.Channel", "Channel") .WithMany() .HasForeignKey("ChannelId"); b.Navigation("Channel"); }); modelBuilder.Entity("ApiTools.Core.SmsSetting", b => { b.HasOne("ApiTools.Core.Channel", "Channel") .WithMany() .HasForeignKey("ChannelId"); b.Navigation("Channel"); }); modelBuilder.Entity("ApiTools.Core.SmsSettingAccess", b => { b.HasOne("ApiTools.Core.SmsSetting", "Setting") .WithMany("Accesses") .HasForeignKey("SettingId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Setting"); }); modelBuilder.Entity("ApiTools.Core.User", b => { b.HasOne("ApiTools.Core.Channel", "Channel") .WithMany() .HasForeignKey("ChannelId"); b.Navigation("Channel"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b => { b.Navigation("PingAnPay"); }); modelBuilder.Entity("ApiTools.Core.SmsSetting", b => { b.Navigation("Accesses"); }); #pragma warning restore 612, 618 } } } ApiTools.Database.Migrations/Migrations/20251119014221_UpdateChannelWallet1119.cs
New file @@ -0,0 +1,185 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable namespace ApiTools.Database.Migrations.Migrations { /// <inheritdoc /> public partial class UpdateChannelWallet1119 : Migration { /// <inheritdoc /> protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "ChannelWallet", columns: table => new { Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), ChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), OutWalletId = table.Column<string>(type: "nvarchar(max)", nullable: true), Access = table.Column<int>(type: "int", nullable: false), Code = table.Column<string>(type: "nvarchar(max)", nullable: true), Bank = table.Column<string>(type: "nvarchar(max)", nullable: true), BankBranch = table.Column<string>(type: "nvarchar(max)", nullable: true), Name = table.Column<string>(type: "nvarchar(max)", nullable: true), Identity = table.Column<string>(type: "nvarchar(max)", nullable: true), Balance = table.Column<decimal>(type: "decimal(18,2)", nullable: false), SignStatus = table.Column<int>(type: "int", nullable: false), ErrorCode = table.Column<string>(type: "nvarchar(max)", nullable: true), FailReason = table.Column<string>(type: "nvarchar(max)", nullable: true), Sort = table.Column<int>(type: "int", nullable: false), TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true), CreatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false), CreatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), CreatedChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), UpdatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true), UpdatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), IsDeleted = table.Column<bool>(type: "bit", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ChannelWallet", x => x.Id); table.ForeignKey( name: "FK_ChannelWallet_Channel_ChannelId", column: x => x.ChannelId, principalTable: "Channel", principalColumn: "Id"); }); migrationBuilder.CreateTable( name: "ChannelWalletTransaction", columns: table => new { Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), WalletId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), Type = table.Column<int>(type: "int", nullable: false), Code = table.Column<string>(type: "nvarchar(max)", nullable: true), OutCode = table.Column<string>(type: "nvarchar(max)", nullable: true), ConcurrencyLock = table.Column<string>(type: "nvarchar(450)", nullable: true), Amount = table.Column<decimal>(type: "decimal(18,2)", nullable: false), Balance = table.Column<decimal>(type: "decimal(18,2)", nullable: false), AfterBalance = table.Column<decimal>(type: "decimal(18,2)", nullable: false), OutOperatorId = table.Column<string>(type: "nvarchar(max)", nullable: true), OperatorTime = table.Column<DateTime>(type: "datetime2", nullable: true), PayerAccount = table.Column<string>(type: "nvarchar(max)", nullable: true), PayerName = table.Column<string>(type: "nvarchar(max)", nullable: true), PayerBank = table.Column<string>(type: "nvarchar(max)", nullable: true), PayerBankBranch = table.Column<string>(type: "nvarchar(max)", nullable: true), OutReceiveId = table.Column<string>(type: "nvarchar(max)", nullable: true), ReceiveName = table.Column<string>(type: "nvarchar(max)", nullable: true), ReceiveIdentity = table.Column<string>(type: "nvarchar(max)", nullable: true), ReceiveAccount = table.Column<string>(type: "nvarchar(max)", nullable: true), ReceiveBank = table.Column<string>(type: "nvarchar(max)", nullable: true), ReceiveBankBranch = table.Column<string>(type: "nvarchar(max)", nullable: true), Currency = table.Column<string>(type: "nvarchar(max)", nullable: true), Purpose = table.Column<string>(type: "nvarchar(max)", nullable: true), Remark = table.Column<string>(type: "nvarchar(max)", nullable: true), ErrorCode = table.Column<string>(type: "nvarchar(max)", nullable: true), FailReason = table.Column<string>(type: "nvarchar(max)", nullable: true), TransDate = table.Column<DateTime>(type: "datetime2", nullable: true), OrderFee = table.Column<decimal>(type: "decimal(18,2)", nullable: true), EreceiptFileId = table.Column<string>(type: "nvarchar(max)", nullable: true), EreceiptDownloadUrl = table.Column<string>(type: "nvarchar(max)", nullable: true), EreceiptDownloadOssUrl = table.Column<string>(type: "nvarchar(max)", nullable: true), EreceiptStatus = table.Column<int>(type: "int", nullable: true), EreceiptErrorMessage = table.Column<string>(type: "nvarchar(max)", nullable: true), TransactionStatus = table.Column<int>(type: "int", nullable: false), Sort = table.Column<int>(type: "int", nullable: false), TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true), CreatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false), CreatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), CreatedChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), UpdatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true), UpdatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), IsDeleted = table.Column<bool>(type: "bit", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ChannelWalletTransaction", x => x.Id); table.ForeignKey( name: "FK_ChannelWalletTransaction_ChannelWallet_WalletId", column: x => x.WalletId, principalTable: "ChannelWallet", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "ChannelWalletTransactionPingAnPay", columns: table => new { Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), FreezeNo = table.Column<string>(type: "nvarchar(max)", nullable: true), StopStt = table.Column<string>(type: "nvarchar(max)", nullable: true), StopFailReason = table.Column<string>(type: "nvarchar(max)", nullable: true), RemoveStopStt = table.Column<string>(type: "nvarchar(max)", nullable: true), RemoveStopFailReason = table.Column<string>(type: "nvarchar(max)", nullable: true), ThirdVoucher = table.Column<string>(type: "nvarchar(max)", nullable: true), FrontLogNo = table.Column<string>(type: "nvarchar(max)", nullable: true), CstInnerFlowNo = table.Column<string>(type: "nvarchar(max)", nullable: true), IsBack = table.Column<string>(type: "nvarchar(max)", nullable: true), BackRem = table.Column<string>(type: "nvarchar(max)", nullable: true), Yhcljg = table.Column<string>(type: "nvarchar(max)", nullable: true), SysFlag = table.Column<string>(type: "nvarchar(max)", nullable: true), Fee = table.Column<string>(type: "nvarchar(max)", nullable: true), TransBsn = table.Column<string>(type: "nvarchar(max)", nullable: true), SubmitTime = table.Column<string>(type: "nvarchar(max)", nullable: true), AccountDate = table.Column<string>(type: "nvarchar(max)", nullable: true), HostFlowNo = table.Column<string>(type: "nvarchar(max)", nullable: true), HostErrorCode = table.Column<string>(type: "nvarchar(max)", nullable: true), ProxyPayName = table.Column<string>(type: "nvarchar(max)", nullable: true), ProxyPayAcc = table.Column<string>(type: "nvarchar(max)", nullable: true), ProxyPayBankName = table.Column<string>(type: "nvarchar(max)", nullable: true), Sort = table.Column<int>(type: "int", nullable: false), TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true), CreatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false), CreatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), CreatedChannelId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), UpdatedTime = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true), UpdatedUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), IsDeleted = table.Column<bool>(type: "bit", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ChannelWalletTransactionPingAnPay", x => x.Id); table.ForeignKey( name: "FK_ChannelWalletTransactionPingAnPay_ChannelWalletTransaction_Id", column: x => x.Id, principalTable: "ChannelWalletTransaction", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateIndex( name: "IX_ChannelWallet_ChannelId", table: "ChannelWallet", column: "ChannelId"); migrationBuilder.CreateIndex( name: "IX_ChannelWalletTransaction_ConcurrencyLock", table: "ChannelWalletTransaction", column: "ConcurrencyLock", unique: true, filter: "[ConcurrencyLock] IS NOT NULL"); migrationBuilder.CreateIndex( name: "IX_ChannelWalletTransaction_WalletId", table: "ChannelWalletTransaction", column: "WalletId"); } /// <inheritdoc /> protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "ChannelWalletTransactionPingAnPay"); migrationBuilder.DropTable( name: "ChannelWalletTransaction"); migrationBuilder.DropTable( name: "ChannelWallet"); } } } ApiTools.Database.Migrations/Migrations/DefaultDbContextModelSnapshot.cs
@@ -66,6 +66,317 @@ b.ToTable("Channel"); }); modelBuilder.Entity("ApiTools.Core.ChannelWallet", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<int>("Access") .HasColumnType("int"); b.Property<decimal>("Balance") .HasColumnType("decimal(18,2)"); b.Property<string>("Bank") .HasColumnType("nvarchar(max)"); b.Property<string>("BankBranch") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("ChannelId") .HasColumnType("uniqueidentifier"); b.Property<string>("Code") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("ErrorCode") .HasColumnType("nvarchar(max)"); b.Property<string>("FailReason") .HasColumnType("nvarchar(max)"); b.Property<string>("Identity") .HasColumnType("nvarchar(max)"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<string>("Name") .HasColumnType("nvarchar(max)"); b.Property<string>("OutWalletId") .HasColumnType("nvarchar(max)"); b.Property<int>("SignStatus") .HasColumnType("int"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.HasIndex("ChannelId"); b.ToTable("ChannelWallet"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<decimal>("AfterBalance") .HasColumnType("decimal(18,2)"); b.Property<decimal>("Amount") .HasColumnType("decimal(18,2)"); b.Property<decimal>("Balance") .HasColumnType("decimal(18,2)"); b.Property<string>("Code") .HasColumnType("nvarchar(max)"); b.Property<string>("ConcurrencyLock") .HasColumnType("nvarchar(450)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("Currency") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptDownloadOssUrl") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptDownloadUrl") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptErrorMessage") .HasColumnType("nvarchar(max)"); b.Property<string>("EreceiptFileId") .HasColumnType("nvarchar(max)"); b.Property<int?>("EreceiptStatus") .HasColumnType("int"); b.Property<string>("ErrorCode") .HasColumnType("nvarchar(max)"); b.Property<string>("FailReason") .HasColumnType("nvarchar(max)"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<DateTime?>("OperatorTime") .HasColumnType("datetime2"); b.Property<decimal?>("OrderFee") .HasColumnType("decimal(18,2)"); b.Property<string>("OutCode") .HasColumnType("nvarchar(max)"); b.Property<string>("OutOperatorId") .HasColumnType("nvarchar(max)"); b.Property<string>("OutReceiveId") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerAccount") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerBank") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerBankBranch") .HasColumnType("nvarchar(max)"); b.Property<string>("PayerName") .HasColumnType("nvarchar(max)"); b.Property<string>("Purpose") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveAccount") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveBank") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveBankBranch") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveIdentity") .HasColumnType("nvarchar(max)"); b.Property<string>("ReceiveName") .HasColumnType("nvarchar(max)"); b.Property<string>("Remark") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<DateTime?>("TransDate") .HasColumnType("datetime2"); b.Property<int>("TransactionStatus") .HasColumnType("int"); b.Property<int>("Type") .HasColumnType("int"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.Property<Guid>("WalletId") .HasColumnType("uniqueidentifier"); b.HasKey("Id"); b.HasIndex("ConcurrencyLock") .IsUnique() .HasFilter("[ConcurrencyLock] IS NOT NULL"); b.HasIndex("WalletId"); b.ToTable("ChannelWalletTransaction"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b => { b.Property<Guid>("Id") .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property<string>("AccountDate") .HasColumnType("nvarchar(max)"); b.Property<string>("BackRem") .HasColumnType("nvarchar(max)"); b.Property<Guid?>("CreatedChannelId") .HasColumnType("uniqueidentifier"); b.Property<DateTimeOffset>("CreatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("CreatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("CstInnerFlowNo") .HasColumnType("nvarchar(max)"); b.Property<string>("Fee") .HasColumnType("nvarchar(max)"); b.Property<string>("FreezeNo") .HasColumnType("nvarchar(max)"); b.Property<string>("FrontLogNo") .HasColumnType("nvarchar(max)"); b.Property<string>("HostErrorCode") .HasColumnType("nvarchar(max)"); b.Property<string>("HostFlowNo") .HasColumnType("nvarchar(max)"); b.Property<string>("IsBack") .HasColumnType("nvarchar(max)"); b.Property<bool>("IsDeleted") .HasColumnType("bit"); b.Property<string>("ProxyPayAcc") .HasColumnType("nvarchar(max)"); b.Property<string>("ProxyPayBankName") .HasColumnType("nvarchar(max)"); b.Property<string>("ProxyPayName") .HasColumnType("nvarchar(max)"); b.Property<string>("RemoveStopFailReason") .HasColumnType("nvarchar(max)"); b.Property<string>("RemoveStopStt") .HasColumnType("nvarchar(max)"); b.Property<int>("Sort") .HasColumnType("int"); b.Property<string>("StopFailReason") .HasColumnType("nvarchar(max)"); b.Property<string>("StopStt") .HasColumnType("nvarchar(max)"); b.Property<string>("SubmitTime") .HasColumnType("nvarchar(max)"); b.Property<string>("SysFlag") .HasColumnType("nvarchar(max)"); b.Property<string>("ThirdVoucher") .HasColumnType("nvarchar(max)"); b.Property<string>("TraceId") .HasColumnType("nvarchar(max)"); b.Property<string>("TransBsn") .HasColumnType("nvarchar(max)"); b.Property<DateTimeOffset?>("UpdatedTime") .HasColumnType("datetimeoffset"); b.Property<Guid?>("UpdatedUserId") .HasColumnType("uniqueidentifier"); b.Property<string>("Yhcljg") .HasColumnType("nvarchar(max)"); b.HasKey("Id"); b.ToTable("ChannelWalletTransactionPingAnPay"); }); modelBuilder.Entity("ApiTools.Core.Resource", b => { b.Property<Guid>("Id") @@ -600,6 +911,37 @@ }); }); modelBuilder.Entity("ApiTools.Core.ChannelWallet", b => { b.HasOne("ApiTools.Core.Channel", "Channel") .WithMany() .HasForeignKey("ChannelId"); b.Navigation("Channel"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b => { b.HasOne("ApiTools.Core.ChannelWallet", "Wallet") .WithMany() .HasForeignKey("WalletId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Wallet"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransactionPingAnPay", b => { b.HasOne("ApiTools.Core.ChannelWalletTransaction", "Transaction") .WithOne("PingAnPay") .HasForeignKey("ApiTools.Core.ChannelWalletTransactionPingAnPay", "Id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Transaction"); }); modelBuilder.Entity("ApiTools.Core.SmsLog", b => { b.HasOne("ApiTools.Core.Channel", "Channel") @@ -638,6 +980,11 @@ b.Navigation("Channel"); }); modelBuilder.Entity("ApiTools.Core.ChannelWalletTransaction", b => { b.Navigation("PingAnPay"); }); modelBuilder.Entity("ApiTools.Core.SmsSetting", b => { b.Navigation("Accesses"); ApiTools.Database.Migrations/REDEME.MD
@@ -1,7 +1,7 @@ -------------------------------主数据库--------------------------------------- 新增迁移文件 dotnet ef migrations add UpdateSmsSetting1009 -s "../ApiTools.Web.Entry" -c DefaultDbContext dotnet ef migrations add UpdateChannelWallet1119 -s "../ApiTools.Web.Entry" -c DefaultDbContext 删除迁移文件 dotnet ef migrations remove -s "../ApiTools.Web.Entry" -c DefaultDbContext ApiTools.Web.Entry/ApiTools.Web.Entry.csproj
@@ -21,6 +21,13 @@ <ProjectReference Include="..\ApiTools.Application\ApiTools.Application.csproj" /> <ProjectReference Include="..\ApiTools.Database.Migrations\ApiTools.Database.Migrations.csproj" /> </ItemGroup> <ItemGroup> <None Update="PingAnPayCert\config.properties"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> <ProjectExtensions> <VisualStudio> <UserProperties properties_4launchsettings_1json__JsonSchema="" /> ApiTools.Web.Entry/PingAnPayCert/config.properties
New file @@ -0,0 +1,8 @@ appId=22c4781c85 publicKey=0480E866C61C385C2916901CFC10AA53DFD89DBFFA87A4A49C26F82C66F30B7A7038D61FDBE08236F6ACFA6216A6FBCC511841586ABE24107438E049BE98C4660C appPrivateKey=7051c204b10e5380859d8e38c3061fbe2d309c4cac1b89f0c331690d291fb18b baseUrl=https://my-st1.orangebank.com.cn:567/fat7/openapi/gateway/ fileUploadUrl=https://my-st1.orangebank.com.cn:567/fat7/openapi/file//boapFile/upload fileDownLoadUrl=https://my-st1.orangebank.com.cn:567/fat7/openapi/file//boapFile/download signMethod=SM2 appSecret=73W620 ApiTools.Web.Entry/Startup.cs
@@ -39,6 +39,7 @@ services.AddComponent<EventBusServiceComponent>(); services.AddComponent<DistributedCacheServiceComponent>(); services.AddComponent<DistributedLockServiceComponent>(); services.AddHttpRemote(); services.AddSingleton<AlipayUtils>(); @@ -59,7 +60,7 @@ { options.BuildSqlType = SqlTypes.SqlServer; options.JobDetail.LogEnabled = true; //options.AddPersistence<DbJobPersistence>(); options.AddPersistence<DbJobPersistence>(); }); services.AddSpecificationDocuments(options =>