/*********************************************************************** * 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 { /// /// 用户提现记录表 接口实现 /// public class CoreCmsUserTocashServices : BaseServices, 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; } /// /// 提现申请 /// /// public async Task 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(); var userServices = container.ServiceProvider.GetService(); var userBankCardServices = container.ServiceProvider.GetService(); var balanceServices = container.ServiceProvider.GetService(); 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; } /// /// 获取用户提现列表记录 /// /// /// /// /// /// public async Task UserToCashList(int userId = 0, int page = 1, int limit = 10, int status = 0) { var jm = new WebApiCallBack(); var where = PredicateBuilder.True(); 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(item.status); if(item.cardNumber!="微信零钱") item.cardNumber = UserHelper.BankCardNoFormat(item.cardNumber); } } jm.status = true; jm.data = list; jm.otherData = new { list.TotalPages }; return jm; } /// /// 提现审核 /// /// /// /// public async Task 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() { 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 重写根据条件查询分页数据 /// /// 重写根据条件查询分页数据 /// /// 判断集合 /// 排序方式 /// 当前页面索引 /// 分布大小 /// /// 是否使用WITH(NOLOCK) /// public async Task> QueryPageAsync(Expression> predicate, Expression> orderByExpression, OrderByType orderByType, int pageIndex = 1, int pageSize = 20, bool blUseNoLock = false) { return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock); } #endregion } }