using cylsg.Core; using cylsg.Model.TransferOrder; using cylsg.Model.UserModel; using cylsg.Model.utilityViewModel; using cylsg.utility; using cylsg.utility.Extend; using Cylsg.Filter; using EzCoreNet.Redis; using EzInitqMessageDef; using EzWechat; using Furion.LinqBuilder; using MapsterMapper; using Newtonsoft.Json; using SKIT.FlurlHttpClient.Wechat.Api.Models; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using TencentCloud.Ame.V20190916.Models; using TencentCloud.Domain.V20180808.Models; using static SKIT.FlurlHttpClient.Wechat.Api.Models.ChannelsLeadsGetLeadsInfoByComponentIdResponse.Types; namespace cylsg.Application.Transfer { /// /// 提现服务程序 /// /// [DynamicApiController] [Authorize] public class UserTransfer { private readonly IEzCoreNetRedisService _redisService; private readonly IWecharPayServicecs _wecharPayServicecs; public UserTransfer(IEzCoreNetRedisService ezCoreNetRedisService,IWecharPayServicecs wecharPayServicecs) { _redisService = ezCoreNetRedisService; _wecharPayServicecs = wecharPayServicecs; } /// /// 提现 /// /// [LimitFilter(LimiType = Limttype.User, timespan = 10, ResponseMeg = "请勿在10秒内重复请求")] public async Task GetTransferMoney([FromQuery] decimal Money) { if (Money < 0.3m) throw Oops.Oh("必须大于0.3元"); if (Money > 2000) throw Oops.Oh("每人每天最多只能提取2000元"); var rs = new BaseRepository(); var UserID = App.User?.FindFirstValue("UserID"); int userid = 0; if (!string.IsNullOrEmpty(UserID)) { userid = int.Parse(UserID); } else { throw Oops.Oh("没有识别到用户收入"); } if (await _redisService.TryLock(StaticStringDef.TransferMoneyLockKey + userid.ToString(), 300)) { try { var UserRs = new BaseRepository(); var user = await UserRs.GetByIdAsync(userid); if (user == null) { throw Oops.Oh($"没有找到用户"); } if (string.IsNullOrEmpty(user.WxOpenId)) { throw Oops.Oh($"用户微信确认失败"); } var uw = await rs.GetFirstAsync(x => x.UserId == userid); if (uw == null) { throw Oops.Oh("该用户没有收入"); } if ((uw.TiXianZonge - uw.YiTiXianJine) < Money) { throw Oops.Oh("用户余额不足"); } var totle = _redisService.Get(StaticStringDef.TransferMoneyManKey + userid.ToString()); if (totle + Money > 2000) { throw Oops.Oh("提现金额不可超出2000"); } var UserTiXianDetailwork = new BaseRepository(); var WeChatTransferOrderwork = new BaseRepository(); if ((uw != null) && (((uw.TiXianZonge??0) - (uw.YiTiXianJine??0)) >= Money)) { //满足条件,发起支付 var TransferOrder = new WeChatTransferOrder { CreateBy = uw.UserId.ToString(), CreateTime = DateTime.Now, // BatchId = _redisService.Get32sn(), OutBatchNumber = _redisService.Get32sn(), Remake = "川印工资支付", TransferDetailList = new List(), UserID = uw.UserId, }; try { await UserTiXianDetailwork.AsTenant().BeginTranAsync(); var moneylist = Money; var maxPayItem = Convert.ToDecimal(App.Configuration["WechartPay:PayMoneyMax"].toInt()); ; while ((moneylist > maxPayItem)) { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = uw.UserId.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)maxPayItem * 100, TransferRemark = "川印工资支付", }); moneylist -= maxPayItem; } if (moneylist <= 0.3m) { //如果这里低于0.3毛,将社区预检,留下次处理 Money -= moneylist; } else { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = uw.UserId.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)(moneylist * 100), TransferRemark = "川印工资支付", }); } TransferOrder.TotalAmount = (int)(Money * 100); TransferOrder.TotalNum = TransferOrder.TransferDetailList.Count(); TransferOrder = await WeChatTransferOrderwork.AsSugarClient().InsertNav(TransferOrder).Include(x => x.TransferDetailList).ExecuteReturnEntityAsync(); await UserTiXianDetailwork.InsertAsync(new UserTiXianDetail { CreateBy = uw.UserId.ToString(), CreateTime = DateTime.Now, UserId = user.Id, ZhiChuShouRu = 0, YiTiXianJine = Money, WeChatTransferOrderID = TransferOrder.Id, Remark = "用户提现" }); //钱包余额调整 uw.YiTiXianJine = (uw.YiTiXianJine??0)+ Money; uw.UpDataBy = uw.UserId.ToString(); uw.UpDataTime = DateTime.Now; await rs.UpdateAsync(uw); await UserTiXianDetailwork.AsTenant().CommitTranAsync(); totle += Money; //设置每日提现限额 _redisService.Add(StaticStringDef.TransferMoneyManKey + userid.ToString(), totle, 60 * 60 * 24); //发起支付 await InitQMessages.SendMessageAsync(InitQMessages.WxTransfer, TransferOrder.Id.ToString()); } catch (Exception) { await UserTiXianDetailwork.AsTenant().RollbackTranAsync(); throw; } // 发起支付 } else { throw Oops.Oh("系统错误"); } } catch (Exception) { throw; } finally { await _redisService.TryUnLock(StaticStringDef.TransferMoneyLockKey + userid.ToString()); } } else throw Oops.Oh("请不要频繁重复申请"); } /// /// 获取为支付列表 /// [AllowAnonymous] [HttpPost] [ApiExplorerSettings(IgnoreApi = true)] public async Task GetTransferOder(SearchTransferOder param) { var WeChatTransferOrderwork = new BaseRepository(); PageModel pageModel = new PageModel { PageIndex = param.PageIndex, PageSize = param.PageSize }; Expression> SearchList = (x) => true; if (!string.IsNullOrEmpty(param.BatchStatus)) { SearchList= SearchList.And(x => x.BatchStatus.Contains(param.BatchStatus)); } if (!string.IsNullOrEmpty(param.NoTBatchStatus)) { var lisstring = param.NoTBatchStatus?.Split('|'); foreach (var lis in lisstring) { SearchList= SearchList.And(x => x.BatchStatus != lis); } } if(param.IsSetOK!=null) { SearchList = SearchList.And(x =>x.IsSetOK==param.IsSetOK); } if (param.HasSendOk == false) SearchList= SearchList.And(x =>( x.FailNum >0||x.BatchStatus!= "FINISHED")||(x.BatchStatus==null&&x.ErrorCode== "NOT_ENOUGH")||x.FailAmount>0); //NOT_ENOUGH 是账户没有钱 else //有一笔大余0 的视为失败 SearchList= SearchList.And(x => x.FailNum ==0&&x.BatchStatus=="FINISHED"); var data=await WeChatTransferOrderwork.AsQueryable().Where(SearchList).Select(x=>new WeChatTransferOrder { BatchRemark= SqlFunc.Subqueryable().Where(uw=>uw.UserId==x.UserID).Select(uw => uw.name+ uw.IdCode) },true).ToPageListAsync(pageModel.PageIndex, pageModel.PageSize,pageModel.TotalCount); //var data = await WeChatTransferOrderwork.GetPageListAsync(SearchList, pageModel); return new TransferOderOut { listdata = data, TotalCount=pageModel.TotalCount, }; } /// /// 重新支付 /// /// 按订单批次操作 /// [AllowAnonymous] [HttpGet] [ApiExplorerSettings(IgnoreApi = true)] public async Task ReSendTransferOder([FromQuery] string ids) { var itmsRes = new BaseRepository(); if (string.IsNullOrEmpty(ids)) throw Oops.Oh("参数错误"); var idsr= ids.Split(',').Select(x=>x.toInt()).ToList(); foreach (var id in idsr) { if (itmsRes.GetById(id) != null) await InitQMessages.SendMessageAsync(InitQMessages.WxTransferAg, id.ToString()); } return true; } /// /// 重新建单 支付 /// /// 订单ID /// [AllowAnonymous] [HttpGet] [ApiExplorerSettings(IgnoreApi = true)] public async Task ReSendCreadTransferMoney([FromQuery] string id) { var itmsRes = new BaseRepository(); if (string.IsNullOrEmpty(id)) throw Oops.Oh("参数错误"); var TOrder = await itmsRes.GetByIdAsync(id.toInt()); if (TOrder == null) { throw Oops.Oh("没有订单需要处理"); } if(TOrder.IsSetOK ==true) { throw Oops.Oh("已经处理不再处理"); } if(!((TOrder.ErrorCode== "INVALID_REQUEST"&&TOrder.ErrorMsg== "对应单号已超出重试期,请查单确认后决定是否换单请求")|| (TOrder.ErrorCode == "NOT_ENOUGH")||(TOrder.FailAmount>0))) { //不满足冲洗支付要求 throw Oops.Oh("不满足重新支付要求"); } var rs = new BaseRepository(); var userid = TOrder.UserID; decimal Money = 0; if (TOrder.FailAmount==null) { decimal overTotal = 0; if (TOrder.BatchId == null) { overTotal = 0;//没有支付单,证明没有支付 } else overTotal = (TOrder.SuccessAmount??0)/100m; //这个是没有创建提交单 按原价重新支付 Money = ((TOrder.TotalAmount??0)/100m)-overTotal; } else Money = (TOrder.FailAmount??0)/100m; if(Money<0.03m) { throw Oops.Oh("失败金额不足0.3元不能再次发起支付"); } if (await _redisService.TryLock(StaticStringDef.TransferMoneyLockKey + userid.ToString(), 300)) { try { var UserRs = new BaseRepository(); var user = await UserRs.GetByIdAsync(userid); if (user == null) { throw Oops.Oh($"没有找到用户"); } if (string.IsNullOrEmpty(user.WxOpenId)) { throw Oops.Oh($"用户微信OpenID确认"); } var uw = await rs.GetFirstAsync(x => x.UserId == userid); if (uw == null) { throw Oops.Oh("该用户没有收入"); } var totle = _redisService.Get(StaticStringDef.TransferMoneyManKey + userid.ToString()); if (totle + Money > 2000) { throw Oops.Oh("提现金额不可超出2000"); } var UserTiXianDetailwork = new BaseRepository(); var WeChatTransferOrderwork = new BaseRepository(); if ((uw != null) && Money<= (uw.TiXianZonge ?? 0)) { //满足条件,发起支付 这里不判断支付金额大鱼可提现余额 var TransferOrder = new WeChatTransferOrder { CreateBy = uw.UserId.ToString(), CreateTime = DateTime.Now, // BatchId = _redisService.Get32sn(), OutBatchNumber = _redisService.Get32sn(), Remake = "川印工资支付", TransferDetailList = new List(), UserID = uw.UserId, RemakeDes = "补充发起支付" , WeChatTransferOrderPrId = TOrder.Id }; try { await UserTiXianDetailwork.AsTenant().BeginTranAsync(); var moneylist = Money; var maxPayItem = Convert.ToDecimal(App.Configuration["WechartPay:PayMoneyMax"].toInt()); ; while ((moneylist > maxPayItem)) { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = uw.UserId.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)maxPayItem * 100, TransferRemark = "川印工资支付" });; moneylist -= maxPayItem; } if (moneylist <= 0.3m) { //如果这里低于0.3毛,将社区预检,留下次处理 Money -= moneylist; } else { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = uw.UserId.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)(moneylist * 100), TransferRemark = "川印工资支付", }); } TransferOrder.TotalAmount = (int)(Money * 100); TransferOrder.TotalNum = TransferOrder.TransferDetailList.Count(); TransferOrder = await WeChatTransferOrderwork.AsSugarClient().InsertNav(TransferOrder).Include(x => x.TransferDetailList).ExecuteReturnEntityAsync(); TOrder.IsSetOK = true; TOrder.RemakeDes = "已经重新建立支付订单 id="+TransferOrder.Id.ToString(); TOrder.UpDataBy = "重新简单支付API"; TOrder.UpDataTime= DateTime.Now; await WeChatTransferOrderwork.UpdateAsync(TOrder); await UserTiXianDetailwork.AsTenant().CommitTranAsync(); totle += Money; //设置每日提现限额 _redisService.Add(StaticStringDef.TransferMoneyManKey + userid.ToString(), totle, 60 * 60 * 24); //发起支付 await InitQMessages.SendMessageAsync(InitQMessages.WxTransfer, TransferOrder.Id.ToString()); } catch (Exception) { await UserTiXianDetailwork.AsTenant().RollbackTranAsync(); throw; } // 发起支付 } else { throw Oops.Oh("没有工作资料或者是提现额度已经大余总额了"); } } catch (Exception) { throw; } finally { await _redisService.TryUnLock(StaticStringDef.TransferMoneyLockKey + userid.ToString()); } } else throw Oops.Oh("请不要频繁重复申请"); } /// /// 重新创建新的支付单 /// /// /// [AllowAnonymous] [HttpPost] [ApiExplorerSettings(IgnoreApi = true)] public async Task CreateTransferOder(CreatTransferOderIN Param) { if(Param.Key!= DateTime.Now.ToString("yyyy-MM-dd:HH")+"CreatTransfer") { //key 错误 throw Oops.Oh("key错误"); } var userbs= new BaseRepository(); //判断是否是用户 var user= await userbs.GetByIdAsync(Param.UserID); if (user == null) throw Oops.Oh("没有用户"); if(Param.Money<=0.3m) { throw Oops.Oh("转账金额必须大余0.3元"); } if (Param.Money >2000) { throw Oops.Oh("一天转账金额必须小于2000"); } if (Param.Money > 2000) { throw Oops.Oh("一天转账金额必须小于2000"); } var totle = _redisService.Get(StaticStringDef.TransferMoneyManKey + Param.UserID.ToString()); if (totle + Param.Money > 2000) { throw Oops.Oh("一天转账金额必须小于2000"); } decimal Money = Param.Money; //满足条件,发起支付 var TransferOrder = new WeChatTransferOrder { CreateBy = Param.UserID.ToString(), CreateTime = DateTime.Now, // BatchId = _redisService.Get32sn(), OutBatchNumber = _redisService.Get32sn(), Remake = "川印工资支付", TransferDetailList = new List(), UserID = Param.UserID, RemakeDes = Param.Remake, }; //是否关联收入钱包表 if (Param.HasAboutReCome) { var UserTiXianDetailwork = new BaseRepository(); var WeChatTransferOrderwork = new BaseRepository(); var rs = new BaseRepository(); var uw = await rs.GetFirstAsync(x => x.UserId == Param.UserID); if(uw==null) { throw Oops.Oh("该用户没有关联钱包"); } //锁定钱包 if (await _redisService.TryLock(StaticStringDef.TransferMoneyLockKey + Param.UserID.ToString(), 300)) { try { await UserTiXianDetailwork.AsTenant().BeginTranAsync(); var moneylist = Money; var maxPayItem = Convert.ToDecimal(App.Configuration["WechartPay:PayMoneyMax"].toInt()); ; while ((moneylist > maxPayItem)) { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = Param.UserID.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)maxPayItem * 100, TransferRemark = "川印工资支付", }); moneylist -= maxPayItem; } if (moneylist <= 0.3m) { //如果这里低于0.3毛,将社区预检,留下次处理 Money -= moneylist; } else { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = Param.UserID.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)(moneylist * 100), TransferRemark = "川印工资支付", }); } TransferOrder.TotalAmount = (int)(Money * 100); TransferOrder.TotalNum = TransferOrder.TransferDetailList.Count(); TransferOrder = await WeChatTransferOrderwork.AsSugarClient().InsertNav(TransferOrder).Include(x => x.TransferDetailList).ExecuteReturnEntityAsync(); await UserTiXianDetailwork.InsertAsync(new UserTiXianDetail { CreateBy = Param.UserID.ToString(), CreateTime = DateTime.Now, UserId = user.Id, ZhiChuShouRu = 0, YiTiXianJine = Money, WeChatTransferOrderID = TransferOrder.Id, Remark = "用户提现" }); //钱包余额调整 uw.YiTiXianJine = (uw.YiTiXianJine ?? 0) + Money; uw.UpDataBy = uw.UserId.ToString(); uw.UpDataTime = DateTime.Now; await rs.UpdateAsync(uw); await UserTiXianDetailwork.AsTenant().CommitTranAsync(); totle += Money; //设置每日提现限额 _redisService.Add(StaticStringDef.TransferMoneyManKey + Param.UserID.ToString(), totle, 60 * 60 * 24); //发起支付 await InitQMessages.SendMessageAsync(InitQMessages.WxTransfer, TransferOrder.Id.ToString()); } catch (Exception) { throw; } finally { //释放 await _redisService.TryUnLock(StaticStringDef.TransferMoneyLockKey + Param.UserID.ToString()); } } else { throw Oops.Oh("系统繁忙,稍后重试"); } } else { //直接转账,不计入钱包记录,主要用于处理超时后无法重新支付的单子 var UserTiXianDetailwork = new BaseRepository(); var WeChatTransferOrderwork = new BaseRepository(); //锁定钱包 if (await _redisService.TryLock(StaticStringDef.TransferMoneyLockKey + Param.UserID.ToString(), 300)) { try { await UserTiXianDetailwork.AsTenant().BeginTranAsync(); var moneylist = Money; var maxPayItem = Convert.ToDecimal(App.Configuration["WechartPay:PayMoneyMax"].toInt()); ; while ((moneylist > maxPayItem)) { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = Param.UserID.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)maxPayItem * 100, TransferRemark = "川印工资支付", }); moneylist -= maxPayItem; } if (moneylist <= 0.3m) { //如果这里低于0.3毛,将社区预检,留下次处理 Money -= moneylist; } else { TransferOrder.TransferDetailList.Add(new WeChatTransferItem { CreateBy = Param.UserID.ToString(), CreateTime = TransferOrder.CreateTime, IsEn = true, OpenId = user.WxOpenId, OutDetailNumber = _redisService.Get32sn(), TransferAmount = (int)(moneylist * 100), TransferRemark = "川印工资支付", }); } TransferOrder.TotalAmount = (int)(Money * 100); TransferOrder.TotalNum = TransferOrder.TransferDetailList.Count(); TransferOrder = await WeChatTransferOrderwork.AsSugarClient().InsertNav(TransferOrder).Include(x => x.TransferDetailList).ExecuteReturnEntityAsync(); await UserTiXianDetailwork.AsTenant().CommitTranAsync(); totle += Money; //设置每日提现限额 _redisService.Add(StaticStringDef.TransferMoneyManKey + Param.UserID.ToString(), totle, 60 * 60 * 24); //发起支付 await InitQMessages.SendMessageAsync(InitQMessages.WxTransfer, TransferOrder.Id.ToString()); } catch (Exception) { throw; } finally { //释放 await _redisService.TryUnLock(StaticStringDef.TransferMoneyLockKey + Param.UserID.ToString()); } } else { throw Oops.Oh("系统繁忙,稍后重试"); } } return TransferOrder; } /// /// 设置为处理状态 /// /// /// [AllowAnonymous] [HttpGet] [ApiExplorerSettings(IgnoreApi = true)] public async Task SetOk([FromQuery] string remark,[FromQuery] string id) { if(string.IsNullOrEmpty(remark)) { throw Oops.Oh("必须要有备注信息"); } if (string.IsNullOrEmpty(id)) { throw Oops.Oh("必须有ID信息"); } var WeChatTransferOrderwork = new BaseRepository(); var oder= await WeChatTransferOrderwork.GetByIdAsync(id.toInt()); if(oder == null) { throw Oops.Oh("没有找到订单"); } if(oder.IsSetOK== true) { throw Oops.Oh("已经处理了"); } oder.IsSetOK = true; oder.RemakeDes = remark; oder.UpDataBy = "API"; oder.UpDataTime= DateTime.Now; await WeChatTransferOrderwork.UpdateAsync(oder); return true; } /// /// 获取列表详情 /// /// [HttpPost] [AllowAnonymous] public async Task> GetTransferOrder(SSPageByWhereOrder Param) { if (Param.Page == null) throw Oops.Oh("参数错误"); Expression> where = null; if (!string.IsNullOrEmpty( Param.Where as string)) { //where = CommonHelper.FormatWhereExpression(Param.Where); where = CommonHelper.FormatWhereExpression(Param.Where as string); } Expression> order = null; if (Param.Order?.Name!=null) { order = CommonHelper.FormatPropertyExpression(Param.Order.Name); } RefAsync title = 0; var BR = new BaseRepository(); var data= await BR.AsQueryable().Includes(x=>x.user,u=>u.Worek).Select(x=>new WeChatTransferOrder { UserIDCode= x.user.Worek.IdCode, UserName=x.user.Worek.name, TotalAmount=x.TotalAmount, TotalNum=x.TotalNum, BatchId=x.BatchId, SuccessNum=x.SuccessNum, OutBatchNumber=x.OutBatchNumber, BatchName = x.BatchName, BatchStatus=x.BatchStatus, UserID= x.UserID, UpDataTime=x.UpDataTime, YiTiXianGz=x.user.Worek.YiTiXianJine, ZhongGz=x.user.Worek.TiXianZonge, ItCode=x.user.ItCode, SuccessAmount= x.SuccessAmount, FailAmount=x.FailAmount }).MergeTable().WhereIF(where != null, where).OrderByIF(order!=null,order,Param.Order?.Des?? OrderByType.Asc).ToPageListAsync(Param.Page.PageIndex,Param.Page.PageSize, title); Param.Page.TotalCount = title; return new RetPageData() { data= data, Page=Param.Page, }; ; } } /// /// 收索 /// public class SearchTransferOder { /// /// 搜索状态值 模糊查询 /// public string BatchStatus { get; set; } /// /// 排除搜索值状态 要排除的状态值必须是全称,多个之间用 “|”间隔 /// public string NoTBatchStatus { get; set; } /// /// 是否已经成功发起了 /// public bool HasSendOk { get; set; } = false; /// /// 当前页码 /// public int PageIndex { get; set; } /// /// 页面大小 /// public int PageSize { get; set; } /// /// 是否特殊处理比如支付失败后已经处理为其他情况 /// public bool? IsSetOK { get; set; } } public class TransferOderOut { public List listdata { get; set; } public int TotalCount { get; set; } } /// /// /// public class CreatTransferOderIN { /// /// 提现金额 /// [Required] public decimal Money { get; set; } /// /// 提现用户 /// [Required] public int UserID { get; set; } /// /// /// [Required] public string Remake{ get; set; } /// /// 操作key /// [Required] public string Key { get; set; } /// /// 是否关联收益 /// [Required] public Boolean HasAboutReCome { get; set; } } }