/***********************************************************************
|
* Project: baifenBinfa
|
* ProjectName: 百分兵法管理系统
|
* Web: http://chuanyin.com
|
* Author:
|
* Email:
|
* CreateTime: 202403/02
|
* Description: 暂无
|
***********************************************************************/
|
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Threading.Tasks;
|
using CoreCms.Net.Caching.AccressToken;
|
using CoreCms.Net.Configuration;
|
using CoreCms.Net.IRepository;
|
using CoreCms.Net.IRepository.UnitOfWork;
|
using CoreCms.Net.IServices;
|
using CoreCms.Net.Loging;
|
using CoreCms.Net.Model.Entities;
|
using CoreCms.Net.Model.Entities.Expression;
|
using CoreCms.Net.Model.ViewModels.Basics;
|
using CoreCms.Net.Model.ViewModels.UI;
|
using CoreCms.Net.Utility.Extensions;
|
using CoreCms.Net.Utility.Helper;
|
using CoreCms.Net.WeChat.Service.HttpClients;
|
using Essensoft.Paylink.WeChatPay;
|
using Essensoft.Paylink.WeChatPay.V2;
|
using Essensoft.Paylink.WeChatPay.V2.Request;
|
using Essensoft.Paylink.WeChatPay.V3.Domain;
|
using Essensoft.Paylink.WeChatPay.V3.Request;
|
using Microsoft.AspNetCore.Http;
|
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Options;
|
using Newtonsoft.Json;
|
using SqlSugar;
|
using Yitter.IdGenerator;
|
using Microsoft.AspNetCore.Hosting;
|
|
|
namespace CoreCms.Net.Services
|
{
|
/// <summary>
|
/// 用户提现记录表 接口实现
|
/// </summary>
|
public class CoreCmsUserTocashServices : BaseServices<CoreCmsUserTocash>, ICoreCmsUserTocashServices
|
{
|
private readonly ICoreCmsUserTocashRepository _dal;
|
private readonly IUnitOfWork _unitOfWork;
|
private readonly IServiceProvider _serviceProvider;
|
private readonly ICoreCmsUserServices _userServices;
|
private readonly ICoreCmsUserBalanceServices _userBalanceServices;
|
private readonly ICoreCmsUserWeChatInfoServices _weChatInfoServices;
|
private readonly IWeChatPayClient _v2Client;
|
private readonly Essensoft.Paylink.WeChatPay.V3.IWeChatPayClient _v3Client;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
private readonly IWebHostEnvironment _webHostEnvironment;
|
private readonly IWeChatPayConfigServices _weChatPayConfigServices;
|
|
|
|
public CoreCmsUserTocashServices(IUnitOfWork unitOfWork, ICoreCmsUserTocashRepository dal,
|
IServiceProvider serviceProvider, ICoreCmsUserServices userServices, ICoreCmsUserBalanceServices userBalanceServices, ICoreCmsUserWeChatInfoServices weChatInfoServices, IWeChatPayClient v2Client, IHttpContextAccessor httpContextAccessor, IWebHostEnvironment webHostEnvironment, Essensoft.Paylink.WeChatPay.V3.IWeChatPayClient v3Client, IWeChatPayConfigServices weChatPayConfigServices)
|
{
|
this._dal = dal;
|
base.BaseDal = dal;
|
_unitOfWork = unitOfWork;
|
_serviceProvider = serviceProvider;
|
_userServices = userServices;
|
_userBalanceServices = userBalanceServices;
|
_weChatInfoServices = weChatInfoServices;
|
_v2Client = v2Client;
|
_httpContextAccessor = httpContextAccessor;
|
_webHostEnvironment = webHostEnvironment;
|
_v3Client = v3Client;
|
_weChatPayConfigServices = weChatPayConfigServices;
|
}
|
|
/// <summary>
|
/// 提现申请
|
/// </summary>
|
/// <returns></returns>
|
public async Task<WebApiCallBack> Tocash(int userId, decimal money, int bankCardsId=0, GlobalEnumVars.UserTocashType type= GlobalEnumVars.UserTocashType.银行线下转账)
|
{
|
var jm = new WebApiCallBack();
|
|
using var container = _serviceProvider.CreateScope();
|
|
var settingServices = container.ServiceProvider.GetService<ICoreCmsSettingServices>();
|
var userServices = container.ServiceProvider.GetService<ICoreCmsUserServices>();
|
var userBankCardServices = container.ServiceProvider.GetService<ICoreCmsUserBankCardServices>();
|
var balanceServices = container.ServiceProvider.GetService<ICoreCmsUserBalanceServices>();
|
|
var allConfigs = await settingServices.GetConfigDictionaries();
|
|
//最小提现金额
|
var tocashMoneyLow = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.TocashMoneyLow).ObjectToDecimal((decimal)0.01);
|
//每日提现上线
|
var tocashMoneyLimit = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.TocashMoneyLimit).ObjectToDecimal(0);
|
//提现手续费
|
var tocashMoneyRate = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.TocashMoneyRate).ObjectToDecimal(0);
|
//最低提现金额
|
if (money < tocashMoneyLow)
|
{
|
jm.msg = "提现最低不能少于" + tocashMoneyLow + "元";
|
return jm;
|
}
|
//每日提现上限,默认0不限制
|
if (tocashMoneyLimit > 0)
|
{
|
var dt = DateTime.Now;
|
var starTime = new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0);
|
var endTime = new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59);
|
//判断历史提现金额
|
var todayMoney = await _dal.GetSumAsync(p => p.createTime >= starTime && p.createTime <= endTime && p.userId == userId, p => p.money);
|
todayMoney = todayMoney + money; //历史今天提现加上本次提现;
|
if (todayMoney > tocashMoneyLimit)
|
{
|
jm.msg = "每日提现不能超过" + tocashMoneyLimit + "元";
|
return jm;
|
}
|
}
|
var userInfo = await userServices.QueryByIdAsync(userId);
|
if (userInfo == null)
|
{
|
jm.msg = GlobalErrorCodeVars.Code11004;
|
return jm;
|
}
|
if (money > userInfo.balance)
|
{
|
jm.msg = GlobalErrorCodeVars.Code11015;
|
return jm;
|
}
|
// 计算提现服务费(金额)
|
var cateMoney = money * (tocashMoneyRate / 100);
|
if (cateMoney + money > userInfo.balance)
|
{
|
jm.msg = GlobalErrorCodeVars.Code11015;
|
return jm;
|
}
|
CoreCmsUserBankCard bankcardsInfo = null;
|
if (type == GlobalEnumVars.UserTocashType.银行线下转账||type== GlobalEnumVars.UserTocashType.企业付款到银行卡)
|
//获取银行卡信息
|
{
|
bankcardsInfo = await userBankCardServices.QueryByClauseAsync(p => p.userId == userId && p.id == bankCardsId);
|
if (bankcardsInfo == null)
|
{
|
jm.msg = GlobalErrorCodeVars.Code11016;
|
return jm;
|
}
|
}
|
var cashModel = new CoreCmsUserTocash();
|
cashModel.userId = userId;
|
cashModel.money = money;
|
cashModel.bankName = bankcardsInfo?.bankName??"微信零钱";
|
cashModel.bankCode = bankcardsInfo?.bankCode?? "微信零钱";
|
cashModel.bankAreaId = bankcardsInfo?.bankAreaId??510000;
|
cashModel.accountBank = bankcardsInfo?.accountBank?? "微信零钱";
|
cashModel.accountName = bankcardsInfo?.accountName?? "微信零钱";
|
cashModel.cardNumber = bankcardsInfo?.cardNumber?? "微信零钱";
|
cashModel.status = (int)GlobalEnumVars.UserTocashStatus.待审核;
|
cashModel.withdrawals = cateMoney;
|
cashModel.createTime = DateTime.Now;
|
cashModel.type = (int)type;
|
|
var res = await _dal.InsertAsync(cashModel);
|
if (res > 0)
|
{
|
var change = await balanceServices.Change(userId, (int)GlobalEnumVars.UserBalanceSourceTypes.Tocash, money, res.ToString(), cateMoney);
|
jm.status = change.status;
|
jm.msg = jm.status ? "提现申请成功" : "提现申请失败";
|
jm.data = change.data;
|
jm.otherData = change.otherData;
|
}
|
else
|
{
|
jm.msg = "提现申请失败";
|
}
|
|
return jm;
|
}
|
|
|
/// <summary>
|
/// 获取用户提现列表记录
|
/// </summary>
|
/// <param name="userId"></param>
|
/// <param name="page"></param>
|
/// <param name="limit"></param>
|
/// <param name="status"></param>
|
/// <returns></returns>
|
public async Task<WebApiCallBack> UserToCashList(int userId = 0, int page = 1, int limit = 10, int status = 0)
|
{
|
var jm = new WebApiCallBack();
|
|
var where = PredicateBuilder.True<CoreCmsUserTocash>();
|
if (status > 0)
|
{
|
where = where.And(p => p.status == status);
|
}
|
if (userId > 0)
|
{
|
where = where.And(p => p.userId == userId);
|
}
|
var list = await _dal.QueryPageAsync(where, p => p.createTime, OrderByType.Desc, page, limit);
|
if (list.Any())
|
{
|
foreach (var item in list)
|
{
|
item.statusName = EnumHelper.GetEnumDescriptionByValue<GlobalEnumVars.UserTocashStatus>(item.status);
|
if(item.cardNumber!="微信零钱")
|
item.cardNumber = UserHelper.BankCardNoFormat(item.cardNumber);
|
}
|
}
|
jm.status = true;
|
jm.data = list;
|
jm.otherData = new
|
{
|
list.TotalPages
|
};
|
return jm;
|
}
|
|
/// <summary>
|
/// 提现审核
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="status"></param>
|
/// <returns></returns>
|
public async Task<WebApiCallBack> Examine(int id = 0, int status = 0, int type = (int)GlobalEnumVars.UserTocashType.银行线下转账)
|
{
|
var jm = new WebApiCallBack();
|
|
var info = await _dal.QueryByClauseAsync(p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
if (info == null)
|
{
|
jm.msg = "没有此记录或不是待审核状态";
|
return jm;
|
}
|
|
switch (type)
|
{
|
case (int)GlobalEnumVars.UserTocashType.银行线下转账 when status > 0:
|
{
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash() { status = status, updateTime = DateTime.Now, type = type }, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
if (bl)
|
{
|
//失败给用户退钱到余额
|
if (status == (int)GlobalEnumVars.UserTocashStatus.提现失败)
|
{
|
var toCashInfo = await _dal.QueryByIdAsync(id);
|
|
// 提现金额 加 服务费返还
|
var newMoney = toCashInfo.money + toCashInfo.withdrawals;
|
var up = await _userServices.UpdateAsync(p => new CoreCmsUser() { balance = p.balance + newMoney }, p => p.id == toCashInfo.userId);
|
if (up)
|
{
|
//添加记录
|
var user = await _userServices.QueryByIdAsync(toCashInfo.userId);
|
|
var balance = new CoreCmsUserBalance();
|
balance.type = (int)GlobalEnumVars.UserBalanceSourceTypes.Tocash;
|
balance.userId = toCashInfo.userId;
|
balance.balance = user.balance;
|
balance.createTime = DateTime.Now;
|
balance.memo = UserHelper.GetMemo(balance.type, toCashInfo.money);
|
balance.money = newMoney;
|
balance.sourceId = id.ToString();
|
|
await _userBalanceServices.InsertAsync(balance);
|
}
|
}
|
}
|
|
break;
|
}
|
case (int)GlobalEnumVars.UserTocashType.银行线下转账:
|
jm.msg = GlobalErrorCodeVars.Code10000;
|
jm.status = false;
|
break;
|
case (int)GlobalEnumVars.UserTocashType.企业付款到零钱:
|
{
|
var user = await _userServices.QueryByIdAsync(info.userId);
|
if (user == null)
|
{
|
jm.msg = "用户信息获取失败";
|
return jm;
|
}
|
var weChatUserInfo = await _weChatInfoServices.QueryByClauseAsync(p => p.userId == info.userId);
|
if (weChatUserInfo == null)
|
{
|
jm.msg = "微信用户数据获取失败";
|
return jm;
|
}
|
|
var config = await _weChatPayConfigServices.QueryByClauseAsync(p => p.isDefault == true && p.isEnable == true);
|
if (config == null)
|
{
|
jm.msg = "支付配置信息获取失败";
|
return jm;
|
}
|
//构建linkPay请求配置实体
|
var payOptions = new WeChatPayOptions
|
{
|
AppId = config.appId,
|
MchId = config.mchId,
|
APIKey = config.apiKey,
|
APIv3Key = config.apiV3Key,
|
Certificate = config.certificate,
|
RsaPublicKey = config.rsaPublicKey,
|
SubAppId = config.subAppId,
|
SubMchId = config.subMchId
|
};
|
|
//按分计算
|
var amount = Convert.ToInt32((info.money - info.withdrawals) * 100);
|
//企业付款到零钱
|
var request = new WeChatPayPromotionTransfersRequest
|
{
|
PartnerTradeNo = YitIdHelper.NextId().ToString(),
|
OpenId = weChatUserInfo.openid,
|
CheckName = "NO_CHECK",
|
ReUserName = info.accountName,
|
Amount = amount,
|
Desc = "余额提现零钱",
|
SpBillCreateIp = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1"
|
};
|
var response = await _v2Client.ExecuteAsync(request, payOptions);
|
if (response.ReturnCode == WeChatPayCode.Success && response.ResultCode == WeChatPayCode.Success)
|
{
|
status = (int)GlobalEnumVars.UserTocashStatus.提现成功;
|
var message = JsonConvert.SerializeObject(response);
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash()
|
{
|
status = status,
|
updateTime = DateTime.Now,
|
message = message,
|
type = type
|
}, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
}
|
else
|
{
|
status = (int)GlobalEnumVars.UserTocashStatus.提现异常;
|
var message = JsonConvert.SerializeObject(response);
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash()
|
{
|
status = status,
|
updateTime = DateTime.Now,
|
message = message,
|
type = type
|
}, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
}
|
|
break;
|
}
|
case (int)GlobalEnumVars.UserTocashType.企业付款到银行卡:
|
{
|
var user = await _userServices.QueryByIdAsync(info.userId);
|
if (user == null)
|
{
|
jm.msg = "用户信息获取失败";
|
return jm;
|
}
|
var weChatUserInfo = await _weChatInfoServices.QueryByClauseAsync(p => p.userId == info.userId);
|
if (weChatUserInfo == null)
|
{
|
jm.msg = "微信用户数据获取失败";
|
return jm;
|
}
|
|
var config = await _weChatPayConfigServices.QueryByClauseAsync(p => p.isDefault == true && p.isEnable == true);
|
if (config == null)
|
{
|
jm.msg = "支付配置信息获取失败";
|
return jm;
|
}
|
//构建linkPay请求配置实体
|
var payOptions = new WeChatPayOptions
|
{
|
AppId = config.appId,
|
MchId = config.mchId,
|
APIKey = config.apiKey,
|
APIv3Key = config.apiV3Key,
|
Certificate = config.certificate,
|
RsaPublicKey = config.rsaPublicKey,
|
SubAppId = config.subAppId,
|
SubMchId = config.subMchId
|
};
|
|
//按分计算
|
var amount = Convert.ToInt32((info.money - info.withdrawals) * 100);
|
//企业付款到零钱
|
var request = new WeChatPayPayBankRequest
|
{
|
PartnerTradeNo = YitIdHelper.NextId().ToString(),
|
BankNo = info.cardNumber,
|
TrueName = info.accountName,
|
BankCode = info.accountBank,
|
Amount = amount,
|
Desc = "余额提现银行卡",
|
};
|
var response = await _v2Client.ExecuteAsync(request, payOptions);
|
if (response.ReturnCode == WeChatPayCode.Success && response.ResultCode == WeChatPayCode.Success)
|
{
|
status = (int)GlobalEnumVars.UserTocashStatus.提现成功;
|
var message = JsonConvert.SerializeObject(response);
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash() { status = status, updateTime = DateTime.Now, message = message, type = type }, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
}
|
else
|
{
|
status = (int)GlobalEnumVars.UserTocashStatus.提现异常;
|
var message = JsonConvert.SerializeObject(response);
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash() { status = status, updateTime = DateTime.Now, message = message, type = type }, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
}
|
|
break;
|
}
|
case (int)GlobalEnumVars.UserTocashType.商家转账到零钱:
|
{
|
var user = await _userServices.QueryByIdAsync(info.userId);
|
if (user == null)
|
{
|
jm.msg = "用户信息获取失败";
|
return jm;
|
}
|
var weChatUserInfo = await _weChatInfoServices.QueryByClauseAsync(p => p.userId == info.userId);
|
if (weChatUserInfo == null)
|
{
|
jm.msg = "微信用户数据获取失败";
|
return jm;
|
}
|
|
var config = await _weChatPayConfigServices.QueryByClauseAsync(p => p.isDefault == true && p.isEnable == true);
|
if (config == null)
|
{
|
jm.msg = "支付配置信息获取失败";
|
return jm;
|
}
|
//构建linkPay请求配置实体
|
var payOptions = new WeChatPayOptions
|
{
|
AppId = config.appId,
|
MchId = config.mchId,
|
APIKey = config.apiKey,
|
APIv3Key = config.apiV3Key,
|
Certificate = config.certificate,
|
RsaPublicKey = config.rsaPublicKey,
|
SubAppId = config.subAppId,
|
SubMchId = config.subMchId
|
};
|
|
//按分计算
|
var amount = Convert.ToInt32((info.money - info.withdrawals) * 100);
|
|
var model = new WeChatPayTransferBatchesBodyModel
|
{
|
AppId = payOptions.AppId,
|
BatchName = info.id + "用户提现处理",
|
BatchRemark = info.id + "用户提现处理",
|
TotalAmount = amount,
|
TotalNum = 1,
|
OutBatchNo = "ut" + info.createTime.ToString("yyyyMMddHHmmss"),
|
TransferDetailList = new List<TransferDetail>()
|
{
|
new()
|
{
|
OutDetailNo = "ut"+ info.createTime.ToString("yyyyMMddHH") + info.id,
|
TransferAmount = amount,
|
TransferRemark = "用户提现处理",
|
OpenId = weChatUserInfo.openid,
|
UserName = info.accountName
|
}
|
}
|
};
|
|
var request = new WeChatPayTransferBatchesRequest();
|
request.SetBodyModel(model);
|
|
var response = await _v3Client.ExecuteAsync(request, payOptions);
|
if (response.IsError == false)
|
{
|
status = (int)GlobalEnumVars.UserTocashStatus.提现成功;
|
var message = JsonConvert.SerializeObject(response);
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash() { status = status, updateTime = DateTime.Now, message = message, type = type }, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
}
|
else
|
{
|
status = (int)GlobalEnumVars.UserTocashStatus.提现异常;
|
var message = JsonConvert.SerializeObject(response);
|
var bl = await _dal.UpdateAsync(p => new CoreCmsUserTocash() { status = status, updateTime = DateTime.Now, message = message, type = type }, p => p.id == id && (p.status == (int)GlobalEnumVars.UserTocashStatus.待审核 || p.status == (int)GlobalEnumVars.UserTocashStatus.提现异常));
|
jm.status = bl;
|
jm.data = status;
|
}
|
break;
|
}
|
|
default:
|
jm.msg = "提现方式获取失败";
|
jm.status = false;
|
break;
|
}
|
return jm;
|
|
|
}
|
|
|
#region 重写根据条件查询分页数据
|
/// <summary>
|
/// 重写根据条件查询分页数据
|
/// </summary>
|
/// <param name="predicate">判断集合</param>
|
/// <param name="orderByType">排序方式</param>
|
/// <param name="pageIndex">当前页面索引</param>
|
/// <param name="pageSize">分布大小</param>
|
/// <param name="orderByExpression"></param>
|
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
|
/// <returns></returns>
|
public async Task<IPageList<CoreCmsUserTocash>> QueryPageAsync(Expression<Func<CoreCmsUserTocash, bool>> predicate,
|
Expression<Func<CoreCmsUserTocash, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
|
int pageSize = 20, bool blUseNoLock = false)
|
{
|
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock);
|
}
|
#endregion
|
|
}
|
}
|