From 3e6b46d6c0c618c67868ea35bde79aa0a53be90b Mon Sep 17 00:00:00 2001 From: zhengyuxuan <zhengyuxuan1995> Date: 星期三, 19 三月 2025 09:43:31 +0800 Subject: [PATCH] fix:新增须知接口 --- LifePayment/LifePayment.Application/LifePay/LifePayService.cs | 830 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 790 insertions(+), 40 deletions(-) diff --git a/LifePayment/LifePayment.Application/LifePay/LifePayService.cs b/LifePayment/LifePayment.Application/LifePay/LifePayService.cs index 8f950fe..2ea55a1 100644 --- a/LifePayment/LifePayment.Application/LifePay/LifePayService.cs +++ b/LifePayment/LifePayment.Application/LifePay/LifePayService.cs @@ -25,7 +25,10 @@ using ZeroD.Util; using ZeroD.Util.Fadd; using static LifePayment.Domain.Shared.LifePaymentConstant; -using static IdentityServer4.Models.IdentityResources; +using Volo.Abp.Data; +using Z.EntityFramework.Plus; +using LifePayment.Domain.LifePay; +using pingan.openbank.api.sdk.enums; namespace LifePayment.Application; @@ -35,8 +38,13 @@ private readonly ILogger<LifePayService> _logger; private readonly IRepository<LifePayRate, Guid> _lifePayRateRepository; + private readonly IRepository<LifePayPremium, Guid> _lifePayPremiumRepository; private readonly IRepository<LifePayOrder, Guid> _lifePayOrderRepository; private readonly IRepository<LifePayUser, Guid> _lifePayUserRepository; + private readonly IRepository<LifePayIntroInfo, Guid> _lifePayIntroInfoRepository; + private readonly IRepository<LifePayChannles, Guid> _lifePayChannlesRep; + private readonly IRepository<LifePayAccount, Guid> _lifePayAccount; + private readonly IDataFilter dataFilter; private readonly IAliPayApi _aliPayApi; private readonly IWxPayApi _wxPayApi; @@ -50,19 +58,29 @@ IRepository<LifePayRate, Guid> lifePayRateRepository, IRepository<LifePayOrder, Guid> lifePayOrderRepository, IRepository<LifePayUser, Guid> lifePayUserRepository, + IRepository<LifePayPremium, Guid> lifePayPremiumRepository, + IRepository<LifePayIntroInfo, Guid> lifePayIntroInfoRepository, IAliPayApi aliPayApi, IWxPayApi wxPayApi, - IOptions<WxPayOption> wxPayOptions) + IOptions<WxPayOption> wxPayOptions, + IRepository<LifePayChannles, Guid> lifePayChannlesRep, + IRepository<LifePayAccount, Guid> lifePayAccount, + IDataFilter dataFilter) { _logger = logger; _aCOOLYManager = aCOOLYManager; _lifePayRateRepository = lifePayRateRepository; _lifePayOrderRepository = lifePayOrderRepository; _lifePayUserRepository = lifePayUserRepository; + _lifePayPremiumRepository = lifePayPremiumRepository; + _lifePayIntroInfoRepository = lifePayIntroInfoRepository; _aliPayApi = aliPayApi; _wxPayApi = wxPayApi; _wxPayOptions = wxPayOptions.Value; _distributedEventBus = distributedEventBus; + _lifePayChannlesRep = lifePayChannlesRep; + _lifePayAccount = lifePayAccount; + this.dataFilter = dataFilter; } #region 鏌ヨ @@ -97,12 +115,52 @@ } /// <summary> + /// 鑾峰彇璇濊垂闈㈠�� + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + public async Task<GasParValueResponse> GetGasParValue() + { + return await _aCOOLYManager.GasParValue(new GasParValueRequestInput()); + } + + /// <summary> + /// 鑾峰彇鐕冩皵鏀寔鍟嗘埛 + /// </summary> + /// <returns></returns> + public async Task<GasOrgTypeValueResponse> GetGasOrgType() + { + return await _aCOOLYManager.GasOrgType(new GasOrgTypeRequestInput()); + } + + /// <summary> /// 鑾峰彇鎶樻墸 /// </summary> /// <returns></returns> public async Task<List<LifePayRateListOutput>> GetRate() { - return await _lifePayRateRepository.Select(x => new LifePayRateListOutput() { Rate = x.Rate, RateType = x.RateType }) + return await _lifePayRateRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayRateListOutput() { Id = x.Id, Rate = x.Rate, RateType = x.RateType }) + .ToListAsync(); + } + + /// <summary> + /// 鑾峰彇鎵嬬画璐硅垂鐜� + /// </summary> + /// <returns></returns> + public async Task<List<LifePayPremiumListOutput>> GetPremium() + { + return await _lifePayPremiumRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayPremiumListOutput() { Id = x.Id, Rate = x.Rate, PremiumType = x.PremiumType }) + .ToListAsync(); + } + + /// <summary> + /// 椤荤煡閰嶇疆 + /// </summary> + /// <returns></returns> + public async Task<List<LifePayIntroInfoOutput>> GetIntroInfo(LifePayOrderTypeEnum lifePayType) + { + return await _lifePayIntroInfoRepository.Where(x => x.IsDeleted == false && x.LifePayType == lifePayType).OrderBy(x => x.Sequence) + .Select(x => new LifePayIntroInfoOutput() { Type = x.Type, ContentSummary = x.ContentSummary, Content = x.Content, LifePayType = x.LifePayType,Path = x.Path,Sequence = x.Sequence }) .ToListAsync(); } @@ -125,42 +183,82 @@ } /// <summary> + /// 鑾峰彇鐢ㄦ埛鎴峰彿鍒嗛〉鏁版嵁 + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + public async Task<PageOutput<UserAccountOutput>> GetAccountPage(QueryUserAccountListInput input) + { + using (dataFilter.Disable<ISoftDelete>()) + { + return await _lifePayAccount.Where(x => x.UserId == input.UserId) + .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayType == input.LifePayOrderType) + .OrderByDescending(x => x.CreationTime) + .Select(x => + new UserAccountOutput + { + Id = x.Id, + LifePayType = x.LifePayType, + Content = x.Content, + CreationTime = x.CreationTime, + Remark = x.Remark, + Operators = x.Operators, + Province = x.Province, + City = x.City, + ExtraProperties = x.ExtraProperties, + IsDeleted = x.IsDeleted + }) + .GetPageResult(input.PageModel); + } + + } + + /// <summary> /// 鑾峰彇璁㈠崟鍒嗛〉鏁版嵁 /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task<PageOutput<LifePayOrderListOutput>> GetLifePayOrderPage(QueryLifePayOrderListInput input) { - return await _lifePayOrderRepository.Where(x => x.PayStatus != LifePayStatusEnum.鏈敮浠�) - .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) + var result = await (from a in _lifePayOrderRepository.Where(x => x.PayStatus != LifePayStatusEnum.鏈敮浠�) + .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) .WhereIf(input.EndFinishTime.HasValue, x => x.FinishTime <= input.EndFinishTime) .WhereIf(input.BeginPayTime.HasValue, x => x.PayTime >= input.BeginPayTime) + .WhereIf(input.LifePayType.HasValue, x => x.LifePayType == input.LifePayType) .WhereIf(input.EndPayTime.HasValue, x => x.PayTime <= input.EndPayTime) .WhereIf(input.LifePayOrderStatus.HasValue, x => x.LifePayOrderStatus == input.LifePayOrderStatus.Value) .WhereIf(input.PayStatus.HasValue, x => x.PayStatus == input.PayStatus.Value) .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayOrderType == input.LifePayOrderType.Value) .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) - .Select(x => - new LifePayOrderListOutput - { - DiscountAmount = x.DiscountAmount, - FinishTime = x.FinishTime, - Id = x.Id, - LifePayOrderStatus = x.LifePayOrderStatus, - LifePayOrderType = x.LifePayOrderType, - LifePayType = x.LifePayType, - OrderNo = x.OrderNo, - PayAmount = x.PayAmount, - PhoneNumber = x.PhoneNumber, - RechargeAmount = x.RechargeAmount, - UserId = x.UserId, - OutOrderNo = x.OutOrderNo, - PayStatus = x.PayStatus, - PayTime = x.PayTime, - RefundCredentialsImgUrl = x.RefundCredentialsImgUrl, - CreationTime = x.CreationTime - }) - .GetPageResult(input.PageModel); + .WhereIf(input.KeyWords.IsNotNullOrEmpty(), x => x.PhoneNumber.Contains(input.KeyWords) || x.OrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords)) + join b in _lifePayChannlesRep on a.ChannelId equals b.Id into temp + from b in temp.DefaultIfEmpty() + select new LifePayOrderListOutput + { + DiscountAmount = a.DiscountAmount, + FinishTime = a.FinishTime, + Id = a.Id, + LifePayOrderStatus = a.LifePayOrderStatus, + LifePayOrderType = a.LifePayOrderType, + LifePayType = a.LifePayType, + OrderNo = a.OrderNo, + PayAmount = a.PayAmount, + PhoneNumber = a.PhoneNumber, + RechargeAmount = a.RechargeAmount, + UserId = a.UserId, + OutOrderNo = a.OutOrderNo, + PayStatus = a.PayStatus, + PayTime = a.PayTime, + ACOOLYOrderNo = a.ACOOLYOrderNo, + RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(), + CreationTime = a.CreationTime, + RefundCheckRemark = a.RefundCheckRemark, + RefundApplyRemark = a.RefundApplyRemark, + RefundTime = a.RefundTime, + ChannelName = b.ChannlesName + }).GetPageResult(input.PageModel); + + return result; } /// <summary> @@ -199,10 +297,45 @@ PayStatus = x.PayStatus, PayTime = x.PayTime, OrderParamDetailJsonStr = x.OrderParamDetailJsonStr, + RefundCredentialsImgUrl = x.RefundCredentialsImgUrl.GetOssPath(), CreationTime = x.CreationTime, - RefundTime = x.RefundTime + RefundCheckRemark = x.RefundCheckRemark, + RefundApplyRemark = x.RefundApplyRemark, + RefundTime = x.RefundTime, + ACOOLYOrderNo = x.ACOOLYOrderNo, }) .GetPageResult(input.PageModel); + } + + public async Task<UserLifePayOrderOutput> GetUserLifePayOrderDetail(string orderNo) + { + var result = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo) + .Select(x => + new UserLifePayOrderOutput + { + DiscountAmount = x.DiscountAmount, + FinishTime = x.FinishTime, + Id = x.Id, + LifePayOrderStatus = x.LifePayOrderStatus, + LifePayOrderType = x.LifePayOrderType, + LifePayType = x.LifePayType, + OrderNo = x.OrderNo, + PayAmount = x.PayAmount, + RechargeAmount = x.RechargeAmount, + PayStatus = x.PayStatus, + PayTime = x.PayTime, + OrderParamDetailJsonStr = x.OrderParamDetailJsonStr, + RefundCredentialsImgUrl = x.RefundCredentialsImgUrl.GetOssPath(), + CreationTime = x.CreationTime, + RefundCheckRemark = x.RefundCheckRemark, + RefundApplyRemark = x.RefundApplyRemark, + RefundTime = x.RefundTime, + ACOOLYOrderNo = x.ACOOLYOrderNo, + }) + .FirstOrDefaultAsync(); + CheckExtensions.IfTrueThrowUserFriendlyException(result == null, "璁㈠崟涓嶅瓨鍦�"); + + return result; } /// <summary> @@ -217,6 +350,184 @@ .FirstOrDefaultAsync(); } + public async Task<PageOutput<CreateEditPayChannelsInput>> GetLifePayChannlesPage(PageInput input) + { + + return await _lifePayChannlesRep.Select(x => + new CreateEditPayChannelsInput + { + Id = x.Id, + ChannlesRate = x.ChannlesRate, + ChannlesName = x.ChannlesName, + ChannlesNum = x.ChannlesNum, + Status = x.Status, + SwitchType = x.SwitchType, + ChannlesType = x.ChannlesType, + }) + .GetPageResult(input.PageModel); + } + + public async Task<CreateEditPayChannelsInput> GetLifePayChannlesDto(Guid id) + { + return await _lifePayChannlesRep.Where(x => x.Id == id).Select(x => + new CreateEditPayChannelsInput + { + Id = x.Id, + ChannlesRate = x.ChannlesRate, + ChannlesName = x.ChannlesName, + ChannlesNum = x.ChannlesNum, + Status = x.Status, + SwitchType = x.SwitchType, + ChannlesType = x.ChannlesType, + }).FirstOrDefaultAsync(); + } + + public async Task<CreateEditPayChannelsInput> GetLifePayChannlesDtoByNum(string channlesNum) + { + var result = await _lifePayChannlesRep.Where(x => x.ChannlesNum == channlesNum && x.Status == LifePayChannelsStatsEnum.鍚敤).Select(x => + new CreateEditPayChannelsInput + { + Id = x.Id, + ChannlesRate = x.ChannlesRate, + ChannlesName = x.ChannlesName, + ChannlesNum = x.ChannlesNum, + Status = x.Status, + SwitchType = x.SwitchType, + ChannlesType = x.ChannlesType, + }).FirstOrDefaultAsync(); + return result; + } + + public async Task<UserLifePayOrderRefundOutput> GetUserLifePayOrderRefund(Guid id) + { + var order = await _lifePayOrderRepository.Where(x => x.Id == id).Select(x => + new UserLifePayOrderRefundOutput + { + Id = x.Id, + OrderNo = x.OrderNo, + RefundCheckRemark = x.RefundCheckRemark, + RefundApplyRemark = x.RefundApplyRemark, + LifePayOrderStatus = x.LifePayOrderStatus, + }).FirstOrDefaultAsync(); + + CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "鏈壘鍒拌鍗曚俊鎭�"); + + return order; + } + + public async Task<PageOutput<UserAccountOutput>> GetUserAccountList(QueryUserAccountListInput input) + { + if (!input.UserId.HasValue) + { + return new PageOutput<UserAccountOutput>(); + } + + var result = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.IsDeleted == false) + .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayType == input.LifePayOrderType) + .OrderByDescending(x => x.CreationTime) + .Select(x => + new UserAccountOutput + { + Id = x.Id, + LifePayType = x.LifePayType, + Content = x.Content, + CreationTime = x.CreationTime, + Remark = x.Remark, + Operators = x.Operators, + Province = x.Province, + City = x.City, + ExtraProperties = x.ExtraProperties, + }) + .GetPageResult(input.PageModel); + return result; + } + + public async Task<List<UserAccountOutput>> GetUserAccountAllList(QueryUserAccountAllListInput input) + { + if (!input.UserId.HasValue) + { + return new List<UserAccountOutput>(); + } + + var result = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.IsDeleted == false) + .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayType == input.LifePayOrderType) + .OrderByDescending(x => x.CreationTime) + .Select(x => + new UserAccountOutput + { + Id = x.Id, + LifePayType = x.LifePayType, + Content = x.Content, + CreationTime = x.CreationTime, + Remark = x.Remark, + Operators = x.Operators, + Province = x.Province, + City = x.City, + ExtraProperties = x.ExtraProperties, + }).ToListAsync(); + return result; + } + + public async Task<UserAccountOutput> GetUserAccountDetail(Guid id) + { + var result = await _lifePayAccount.Where(x => x.Id == id) + .OrderByDescending(x => x.CreationTime) + .Select(x => + new UserAccountOutput + { + Id = x.Id, + LifePayType = x.LifePayType, + Content = x.Content, + CreationTime = x.CreationTime, + Remark = x.Remark, + Operators = x.Operators, + Province = x.Province, + City = x.City, + ExtraProperties = x.ExtraProperties, + }).FirstOrDefaultAsync(); + + CheckExtensions.IfTrueThrowUserFriendlyException(result == null, "鏈壘鍒版埛鍙蜂俊鎭�"); + return result; + } + + public async Task<List<LifePayOrderListTemplate>> GetLifePayOrderPageExport(QueryLifePayOrderListInput input) + { + var result = await (await GetLifePayOrderListFilter(input)).Select(x => new LifePayOrderListTemplate + { + DiscountAmount = x.DiscountAmount, + FinishTime = x.FinishTime, + LifePayOrderStatus = x.LifePayOrderStatus, + LifePayOrderType = x.LifePayOrderType, + LifePayType = x.LifePayType, + OrderNo = x.OrderNo, + PayAmount = x.PayAmount, + PhoneNumber = x.PhoneNumber, + RechargeAmount = x.RechargeAmount, + OutOrderNo = x.OutOrderNo, + PayStatus = x.PayStatus, + PayTime = x.PayTime, + ACOOLYOrderNo = x.ACOOLYOrderNo, + CreationTime = x.CreationTime, + RefundApplyRemark = x.RefundApplyRemark, + ChannelName = x.ChannelName + }).OrderByDescending(r => r.CreationTime).ToListAsync(); + var i = 0; + result.ForEach(s => + { + s.SerialNumber = ++i; + s.LifePayOrderTypeStr = s.LifePayOrderType.GetDescription(); + s.CreationTimeStr = s.CreationTime.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm); + s.RechargeAmountStr = s.RechargeAmount.ToString("F2"); + s.PayAmountStr = s.PayAmount.ToString("F2"); + s.PayTimeStr = !s.PayTime.HasValue ? string.Empty : s.PayTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm); + s.LifePayTypeStr = s.LifePayType.GetDescription(); + s.PayStatusStr = s.PayStatus.GetDescription(); + s.LifePayOrderStatusStr = s.LifePayOrderStatus.GetDescription(); + s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm); + }); + return result; + } + #endregion #region 鎿嶄綔 @@ -228,8 +539,14 @@ /// <returns></returns> public async Task<CreateLifePayOrderOutput> CreateLifePayPhoneOrder(CreateLifePayOrderInput<LifePhoneData> input) { + CheckExtensions.IfTrueThrowUserFriendlyException(input.ProductData.IspCode == "dianxin" && string.IsNullOrEmpty(input.ProductData.Name), "鐢典俊鎵嬫満鍙峰繀濉満涓诲悕"); + + var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == input.UserId); CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "鐢ㄦ埛涓嶅瓨鍦紝璇峰厛鐧诲綍鍐嶆搷浣�"); + + var channle = await GetLifePayChannlesDtoByNum(input.ChannelId); + CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "娓犻亾涓嶅瓨鍦�"); var rate = await GetRate(); CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "鏈厤缃姌鎵�"); @@ -249,6 +566,7 @@ PayAmount = amount.PayAmont, DiscountAmount = amount.DiscountAmount, RechargeAmount = amount.RechargeAmount, + ChannelId = channle.Id }; await CreateLifePayOrder(orderInput); @@ -270,6 +588,10 @@ var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == input.UserId); CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "鐢ㄦ埛涓嶅瓨鍦紝璇峰厛鐧诲綍鍐嶆搷浣�"); + var channle = await GetLifePayChannlesDtoByNum(input.ChannelId); + CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "娓犻亾涓嶅瓨鍦�"); + CheckExtensions.IfTrueThrowUserFriendlyException(channle.Status == LifePayChannelsStatsEnum.绂佺敤, "娓犻亾宸茶绂佺敤"); + var rate = await GetRate(); CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "鏈厤缃姌鎵�"); @@ -288,6 +610,51 @@ PayAmount = amount.PayAmont, DiscountAmount = amount.DiscountAmount, RechargeAmount = amount.RechargeAmount, + ChannelId = channle.Id + }; + + await CreateLifePayOrder(orderInput); + + var result = new CreateLifePayOrderOutput() + { + OrderNo = orderInput.OrderNo, + }; + return result; + } + + /// <summary> + /// 鍒涘缓鐢熸椿缂磋垂鐕冩皵璁㈠崟 + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + public async Task<CreateLifePayOrderOutput> CreateLifePayGasOrder(CreateLifePayOrderInput<LifeGasData> input) + { + var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == input.UserId); + CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "鐢ㄦ埛涓嶅瓨鍦紝璇峰厛鐧诲綍鍐嶆搷浣�"); + + var channle = await GetLifePayChannlesDtoByNum(input.ChannelId); + CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "娓犻亾涓嶅瓨鍦�"); + CheckExtensions.IfTrueThrowUserFriendlyException(channle.Status == LifePayChannelsStatsEnum.绂佺敤, "娓犻亾宸茶绂佺敤"); + + var rate = await GetRate(); + CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "鏈厤缃姌鎵�"); + + var amount = CalculateAmount(input.ProductData.ParValue, rate.FirstOrDefault(x => x.RateType == LifePayRateTypeEnum.榛樿鐕冩皵鎶樻墸).Rate); + + var orderInput = new CreateLifePayOrderInput + { + OrderNo = CreateOrderNo(), + LifePayOrderStatus = LifePayOrderStatusEnum.寰呯‘璁�, + LifePayOrderType = LifePayOrderTypeEnum.鐕冩皵璁㈠崟, + // LifePayType = input.LifePayType, + OrderParamDetailJsonStr = JsonConvert.SerializeObject(input.ProductData), + UserId = user.Id, + PayStatus = LifePayStatusEnum.鏈敮浠�, + PhoneNumber = user.PhoneNumber, + PayAmount = amount.PayAmont, + DiscountAmount = amount.DiscountAmount, + RechargeAmount = amount.RechargeAmount, + ChannelId = channle.Id }; await CreateLifePayOrder(orderInput); @@ -363,6 +730,9 @@ case LifePayOrderTypeEnum.鐢佃垂璁㈠崟: desc += "鐢佃垂"; break; + case LifePayOrderTypeEnum.鐕冩皵璁㈠崟: + desc += "鐕冩皵"; + break; default: break; } @@ -373,12 +743,10 @@ // var result = await PayTransactionsJsAPI(input.OpenId, input.Attach, order.PayAmount, input.OrderNo, desc); - var result = await PayTransactionsJsAPI(input.OpenId, input.Attach, order.PayAmount, input.OrderNo, desc); + var result = await PayTransactionsJsAPI(input.OpenId, input.PayAppId, input.Attach, order.PayAmount, input.OrderNo, desc); return result; //var payUrl = await GetPayQRCode(order.LifePayType.Value, order.OrderNo, desc, 0.01m, ip, input.H5Type); //var payUrl = await GetPayQRCode(order.LifePayType.Value, order.OrderNo, desc, order.PayAmount, ip, input.H5Type); - - } @@ -454,14 +822,46 @@ return (result.Code, requestInput.RequestNo, result.ElectricChargeOrder.BusiOrderNo); } - public async Task<ModelPaymentMiniPay> PayTransactionsJsAPI(string openid, string order_guid, decimal amount, string outTradeNo, string description) + /// <summary> + /// 鍒涘缓ACOOLY鐕冩皵璁㈠崟 + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYGasOrder(LifeGasData input, string orderNo) { - string time_expire = DateTime.Now.AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00";//璁㈠崟澶辨晥鏃堕棿 + var requestInput = new ConfirmGasOrderRequestInput() + { + GasOrgType = input.GasOrgType, + ParValue = input.ParValue, + GasAccount = input.GasAccount, + OutOrderNo = orderNo, + AreaName = input.Province + "-" + input.City + }; + var result = await _aCOOLYManager.ConfirmGasOrder(requestInput); +#if DEBUG + + _logger.LogInformation($"CreateACOOLYGasOrder:{JsonConvert.SerializeObject(result)}"); + +#endif + + CheckExtensions.IfTrueThrowUserFriendlyException(!result.Success || (result.Code != ACOOLYConstant.Code.SUCCESS && result.Code != ACOOLYConstant.Code.PROCESSING), + "璋冪敤ACOOLY鎺ュ彛ConfirmElectricOrder杩斿洖閿欒:" + JsonConvert.SerializeObject(result)); + + return (result.Code, requestInput.RequestNo, result.GasChargeOrder.BusiOrderNo); + } + + public async Task<ModelPaymentMiniPay> PayTransactionsJsAPI(string openid, string appId, string order_guid, decimal amount, string outTradeNo, string description) + { + string time_expire = DateTime.Now.AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00"; /// 璁㈠崟澶辨晥鏃堕棿 + if (string.IsNullOrEmpty(appId)) + { + appId = _wxPayOptions.AppID; + } + ModelMiniPayRequest req = new ModelMiniPayRequest { - TimeExpire = time_expire, - Appid = _wxPayOptions.AppID, + Appid = appId, Mchid = _wxPayOptions.Mchid, Attach = order_guid, Description = description, @@ -486,7 +886,7 @@ if (res != null) { - string paytext = BuildSignByPay(_wxPayOptions.AppID, timestamp, nonce, package); + string paytext = BuildSignByPay(appId, timestamp, nonce, package); string paysign = _wxPayApi.GeneratePaySignByKey(paytext); info.Timestamp = timestamp.ToString(); @@ -542,6 +942,9 @@ break; case LifePayOrderTypeEnum.鐢佃垂璁㈠崟: result = await CreateACOOLYElectricOrder(JsonConvert.DeserializeObject<LifeElectricData>(order.OrderParamDetailJsonStr), order.OrderNo); + break; + case LifePayOrderTypeEnum.鐕冩皵璁㈠崟: + result = await CreateACOOLYGasOrder(JsonConvert.DeserializeObject<LifeGasData>(order.OrderParamDetailJsonStr), order.OrderNo); break; default: break; @@ -613,14 +1016,20 @@ return; } - if (order.LifePayOrderStatus != LifePayOrderStatusEnum.宸插け璐� && order.PayStatus != LifePayStatusEnum.寰呴��娆�) + if (order.LifePayOrderStatus != LifePayOrderStatusEnum.宸插け璐� && order.PayStatus != LifePayStatusEnum.寰呴��娆� && order.LifePayOrderStatus != LifePayOrderStatusEnum.閫�娆惧緟瀹℃牳) { throw new UserFriendlyException("褰撳墠璁㈠崟鐘舵�佹棤娉曢��娆�"); } + /// TODO 閫�娆捐姹傚畬鎴愬悗濡備綍鎿嶄綔 + /// var refundResult = await WxPayDomesticRefunds(order.OrderNo, order.RefundApplyRemark, Convert.ToInt32(order.PayAmount * 100), Convert.ToInt32(order.PayAmount * 100)); + order.PayStatus = LifePayStatusEnum.宸查��娆�; + order.LifePayOrderStatus = LifePayOrderStatusEnum.宸查��娆�; order.RefundCredentialsImgUrl = input.RefundCredentialsImgUrl; + order.RefundCheckRemark = input.RefundCheckRemark; order.RefundTime = DateTime.Now; + order.RefundCheckUserId = CurrentUser.Id; await _lifePayOrderRepository.UpdateAsync(order); @@ -632,6 +1041,298 @@ } + /// <summary> + /// 鐢ㄦ埛鍙戣捣鐢熸椿缂磋垂閫�娆� + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + /// <exception cref="UserFriendlyException"></exception> + public async Task RefundUserLifePayOrder(RefundUserLifePayOrderInput input) + { + var order = await _lifePayOrderRepository.FirstOrDefaultAsync(x => x.Id == input.Id); + CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "璁㈠崟涓嶅瓨鍦�"); + if (order.UserId != input.UserId) + { + throw new UserFriendlyException("闈炵敤鎴锋湰浜洪��娆�"); + } + + if (order.PayStatus == LifePayStatusEnum.宸查��娆�) + { + return; + } + + if (order.LifePayOrderStatus != LifePayOrderStatusEnum.寰呯‘璁� && order.LifePayOrderStatus != LifePayOrderStatusEnum.宸插け璐� + && order.PayStatus != LifePayStatusEnum.宸叉敮浠�) + { + throw new UserFriendlyException("褰撳墠璁㈠崟鐘舵�佹棤娉曠敵璇烽��娆�"); + } + + order.LifePayOrderStatus = LifePayOrderStatusEnum.閫�娆惧緟瀹℃牳; + order.RefundApplyRemark = input.RefundApplyRemark; + order.RefundTime = DateTime.Now; + + await _lifePayOrderRepository.UpdateAsync(order); + } + + public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(string outTradeNo, string reason, int refund, int total, string currency = "CNY") + { + WxPayDomesticRefundsRequest req = new WxPayDomesticRefundsRequest + { + OutTradeNo = outTradeNo, + OutRefundNo = CreateRefundOrderNo(), + Reason = reason, + Amount = new Model_WxPayDomesticRefunds_Amount + { + Refund = refund, + Total = total, + Currency = "CNY" + }, + NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxPayDomesticRefundsNotifySectionUrl}", + }; + + var res = await _wxPayApi.WxPayDomesticRefunds(req); + return res; + } + + public async Task<int> AddUpdateUserAccount(AddUpdateUserAccountInput input) + { + if (input.Id.HasValue) + { + var userAccount = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.Id == input.Id) + .FirstOrDefaultAsync(); + CheckExtensions.IfTrueThrowUserFriendlyException(userAccount == null, "鎴峰彿涓嶅瓨鍦�"); + var repeatAccountContent = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.LifePayType == input.LifePayType && x.Content == input.Content && x.Id != input.Id) + .FirstOrDefaultAsync(); + CheckExtensions.IfTrueThrowUserFriendlyException(repeatAccountContent != null, "鎴峰彿宸插瓨鍦�"); + + userAccount.LifePayType = input.LifePayType; + userAccount.Content = input.Content; + userAccount.Province = input.Province; + userAccount.City = input.City; + userAccount.Remark = input.Remark; + userAccount.Operators = input.Operators; + userAccount.ExtraProperties = input.ExtraProperties; + } + else + { + var repeatAccountContent = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.LifePayType == input.LifePayType && x.Content == input.Content) + .FirstOrDefaultAsync(); + CheckExtensions.IfTrueThrowUserFriendlyException(repeatAccountContent != null, "鎴峰彿宸插瓨鍦�"); + var userAccount = new LifePayAccount + { + Id = Guid.NewGuid(), + UserId = input.UserId, + Content = input.Content, + Province = input.Province, + LifePayType = input.LifePayType, + City = input.City, + Remark = input.Remark, + Operators = input.Operators, + ExtraProperties = input.ExtraProperties, + }; + await _lifePayAccount.InsertAsync(userAccount); + } + + return Constant.SUCCESS; + } + + /// <summary> + /// 鐢ㄦ埛鍒犻櫎鎴峰彿淇℃伅 + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + public async Task<int> DeleteUserAccount(Guid id) + { + var userAccount = await _lifePayAccount.Where(x => x.Id == id) + .FirstOrDefaultAsync(); + CheckExtensions.IfTrueThrowUserFriendlyException(userAccount == null, "鎴峰彿涓嶅瓨鍦�"); + userAccount.DeleterId = userAccount.UserId; + userAccount.DeletionTime = DateTime.Now; + userAccount.IsDeleted = true; + return Constant.SUCCESS; + } + + /// <summary> + /// 閫�娆鹃┏鍥� + /// </summary> + /// <param name="input"></param> + /// <returns></returns> + /// <exception cref="UserFriendlyException"></exception> + public async Task RejectRefundLifePayOrder(RefundLifePayOrderInput input) + { + var order = await _lifePayOrderRepository.FirstOrDefaultAsync(x => x.Id == input.Id); + CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "璁㈠崟涓嶅瓨鍦�"); + + if (order.PayStatus == LifePayStatusEnum.宸查��娆�) + { + return; + } + + if ((order.LifePayOrderStatus == LifePayOrderStatusEnum.宸插け璐� && order.PayStatus == LifePayStatusEnum.寰呴��娆�) || + order.LifePayOrderStatus == LifePayOrderStatusEnum.閫�娆惧緟瀹℃牳 || order.LifePayOrderStatus == LifePayOrderStatusEnum.寰呯‘璁�) + { + order.LifePayOrderStatus = LifePayOrderStatusEnum.閫�娆惧け璐�; + order.RefundCheckRemark = input.RefundCheckRemark; + order.RefundCheckUserId = CurrentUser.Id; + + await _lifePayOrderRepository.UpdateAsync(order); + + #region 璁板綍鏃ュ織 + + await PublishLifePayOrderHistoryEvent("閫�娆鹃┏鍥�", "閫�娆�", order.Id); + + #endregion + } + else + { + throw new UserFriendlyException("褰撳墠璁㈠崟鐘舵�佹棤娉曢��娆�"); + } + + + } + + public async Task CreateEditPayChannels(CreateEditPayChannelsInput input) + { + if (input.Id.HasValue) + { + var dto = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.Id == input.Id.Value); + CheckExtensions.IfTrueThrowUserFriendlyException(dto == null, "鏈幏鍙栧埌娓犻亾鎶樻墸鏁版嵁"); + dto.ChannlesName = input.ChannlesName; + dto.ChannlesNum = input.ChannlesNum; + dto.ChannlesRate = input.ChannlesRate; + dto.SwitchType = input.SwitchType; + dto.ChannlesType = input.ChannlesType; + dto.Status = input.Status; + #region 璁板綍鏃ュ織 + + await PublishLifePayOrderHistoryEvent("娓犻亾绠$悊", "缂栬緫", input.Id.Value, TableType.LifePayChannles); + + #endregion + } + else + { + CheckExtensions.IfTrueThrowUserFriendlyException(input.ChannlesRate < 0.01m, "娓犻亾鎶樻墸璁剧疆閿欒"); + input.Id = Guid.NewGuid(); + var entity = ObjectMapper.Map<CreateEditPayChannelsInput, LifePayChannles>(input); + await _lifePayChannlesRep.InsertAsync(entity); + + #region 璁板綍鏃ュ織 + + await PublishLifePayOrderHistoryEvent("娓犻亾绠$悊", "鏂板", input.Id.Value, TableType.LifePayChannles); + + #endregion + } + + + } + + public async Task SetLifePayChannelsStatus(Guid id, LifePayChannelsStatsEnum status) + { + await _lifePayChannlesRep.Where(r => r.Id == id).UpdateAsync(r => new LifePayChannles + { + Status = status, + }); + + #region 璁板綍鏃ュ織 + + await PublishLifePayOrderHistoryEvent("娓犻亾绠$悊", status.GetDescription(), id, TableType.LifePayChannles); + + #endregion + } + + public async Task<bool> CheckChannelsStatus(string channlesId) + { + var dto = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == channlesId); + CheckExtensions.IfTrueThrowUserFriendlyException(dto == null, "褰撳墠娓犻亾鍟嗕笉瀛樺湪"); + CheckExtensions.IfTrueThrowUserFriendlyException(dto.Status == LifePayChannelsStatsEnum.绂佺敤, "褰撳墠娓犻亾鍟嗗凡绂佺敤"); + return true; + } + + public async Task CreateEditLifePayRate(List<LifePayRateInput> input) + { + CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate <= 0).Any(), "鎶樻墸涓嶅緱灏忎簬绛変簬0"); + var baseRate = input.FirstOrDefault(r => r.RateType == LifePayRateTypeEnum.渚涘簲鍟嗘姌鎵d环)?.Rate; + var listData = new List<LifePayRate>(); + foreach (var item in input) + { + CheckExtensions.IfTrueThrowUserFriendlyException(item.Rate < (baseRate ?? 0), "鎶樻墸涓嶅緱灏忎簬渚涘簲鍟嗘姌鎵�"); + var tmpDto = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == item.RateType); + if (tmpDto != null) + { + tmpDto.Rate = item.Rate; + } + else + { + listData.Add(new LifePayRate + { + CreationTime = DateTime.Now, + Rate = item.Rate, + RateType = item.RateType, + Id = Guid.NewGuid(), + }); + } + } + + if (listData.Any()) + { + await _lifePayRateRepository.InsertManyAsync(listData); + } + } + + public async Task CreateEditLifePayPremium(List<LifePayPremiumInput> input) + { + CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate < 0).Any(), "鎶樻墸涓嶅緱灏忎簬0"); + var listData = new List<LifePayPremium>(); + foreach (var item in input) + { + var tmpDto = await _lifePayPremiumRepository.FirstOrDefaultAsync(r => r.PremiumType == item.PremiumType); + if (tmpDto != null) + { + tmpDto.Rate = item.Rate; + } + else + { + listData.Add(new LifePayPremium + { + CreationTime = DateTime.Now, + Rate = item.Rate, + PremiumType = item.PremiumType, + Id = Guid.NewGuid(), + }); + } + } + + if (listData.Any()) + { + await _lifePayPremiumRepository.InsertManyAsync(listData); + } + } + + public async Task EditIntroInfo(LifePayIntroInfoInput input) + { + var listData = new List<LifePayIntroInfo>(); + foreach (var item in input.Data) + { + var tmpDto = await _lifePayIntroInfoRepository.Where(r => r.LifePayType == input.LifePayType).DeleteAsync(); + + listData.Add(new LifePayIntroInfo + { + LifePayType = input.LifePayType, + CreationTime = DateTime.Now, + Type = item.Type, + ContentSummary = item.ContentSummary, + Content = item.Content, + Path = item.Path, + Sequence = item.Sequence, + Id = Guid.NewGuid(), + }); + } + + if (listData.Any()) + { + await _lifePayIntroInfoRepository.InsertManyAsync(listData); + } + } #endregion #region 绉佹湁 @@ -641,9 +1342,19 @@ return "JF" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GlobalRandom.GetRandomNum(4); } + private string CreateRefundOrderNo() + { + return "JFTK" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GlobalRandom.GetRandomNum(4); + } + private (decimal PayAmont, decimal DiscountAmount, decimal RechargeAmount) CalculateAmount(decimal amount, decimal rate) { - var payAmount = decimal.Round(amount * rate, 2, MidpointRounding.AwayFromZero); + /// 姝e父鏀粯 + var payAmount = decimal.Round(amount * rate / 100, 2, MidpointRounding.AwayFromZero); + + /// 1鍒嗛挶鏀粯 + //decimal payAmount = 0.01m; + CheckExtensions.IfTrueThrowUserFriendlyException(payAmount < 0.01m, "鏀粯閲戦閿欒"); return (payAmount, amount - payAmount, amount); @@ -697,9 +1408,6 @@ { var codeUrl = string.Empty; switch (payType) - - - { case LifePayTypeEnum.AliPay: codeUrl = await GetAliPayQRCode(outTradeNo, description, amount); @@ -834,5 +1542,47 @@ } + private async Task<IQueryable<LifePayOrderListOutput>> GetLifePayOrderListFilter(QueryLifePayOrderListInput input) + { + var result = (from a in _lifePayOrderRepository.Where(x => x.PayStatus != LifePayStatusEnum.鏈敮浠�) + .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) + .WhereIf(input.EndFinishTime.HasValue, x => x.FinishTime <= input.EndFinishTime) + .WhereIf(input.BeginPayTime.HasValue, x => x.PayTime >= input.BeginPayTime) + .WhereIf(input.EndPayTime.HasValue, x => x.PayTime <= input.EndPayTime) + .WhereIf(input.LifePayOrderStatus.HasValue, x => x.LifePayOrderStatus == input.LifePayOrderStatus.Value) + .WhereIf(input.PayStatus.HasValue, x => x.PayStatus == input.PayStatus.Value) + .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayOrderType == input.LifePayOrderType.Value) + .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) + .WhereIf(input.KeyWords.IsNotNullOrEmpty(), x => x.PhoneNumber.Contains(input.KeyWords) || x.OrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords)) + join b in _lifePayChannlesRep on a.ChannelId equals b.Id into temp + from b in temp.DefaultIfEmpty() + select new LifePayOrderListOutput + { + DiscountAmount = a.DiscountAmount, + FinishTime = a.FinishTime, + Id = a.Id, + LifePayOrderStatus = a.LifePayOrderStatus, + LifePayOrderType = a.LifePayOrderType, + LifePayType = a.LifePayType, + OrderNo = a.OrderNo, + PayAmount = a.PayAmount, + PhoneNumber = a.PhoneNumber, + RechargeAmount = a.RechargeAmount, + UserId = a.UserId, + OutOrderNo = a.OutOrderNo, + PayStatus = a.PayStatus, + PayTime = a.PayTime, + ACOOLYOrderNo = a.ACOOLYOrderNo, + RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(), + CreationTime = a.CreationTime, + RefundCheckRemark = a.RefundCheckRemark, + RefundApplyRemark = a.RefundApplyRemark, + RefundTime = a.RefundTime, + ChannelName = b.ChannlesName + }); + return result; + } + + #endregion } -- Gitblit v1.9.1