|  |  | 
 |  |  | using Volo.Abp.EventBus.Distributed; | 
 |  |  | using Z.EntityFramework.Plus; | 
 |  |  | using ZeroD.Util; | 
 |  |  | using Alipay.EasySDK.Payment.Common.Models; | 
 |  |  | using static LifePayment.Domain.Shared.LifePaymentConstant; | 
 |  |  | using ZeroD.Util.Fadd; | 
 |  |  | using Nest; | 
 |  |  |  | 
 |  |  | namespace LifePayment.Application; | 
 |  |  |  | 
 |  |  | 
 |  |  |     { | 
 |  |  |         return await _channelFilter.GetChannelLifePayUserFilter(_lifePayUserRepository).Where(x => x.IsDeleted == false) | 
 |  |  |             .WhereIf(!string.IsNullOrEmpty(input.QueryCondition), x => x.PhoneNumber.Contains(input.QueryCondition) || x.Name.Contains(input.QueryCondition)) | 
 |  |  |             .WhereIf(input.CreationTime.HasValue, x => x.CreationTime.ToString("yyyy-MM-dd") == input.CreationTime.Value.ToString("yyyy-MM-dd")) | 
 |  |  |             .WhereIf(input.CreationTimeBegin.HasValue, x => x.CreationTime >= input.CreationTimeBegin) | 
 |  |  |             .WhereIf(input.CreationTimeEnd.HasValue, x => x.CreationTime <= input.CreationTimeEnd) | 
 |  |  |                                             .Select(x => | 
 |  |  |                                                    new UserListOutput() | 
 |  |  |                                                    { | 
 |  |  | 
 |  |  |     /// <returns></returns> | 
 |  |  |     public async Task<PageOutput<LifePayOrderListOutput>> GetLifePayOrderPage(QueryLifePayOrderListInput input) | 
 |  |  |     { | 
 |  |  |  | 
 |  |  |         var result = await (from a in _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository) | 
 |  |  |                       .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) | 
 |  |  |                                             .WhereIf(input.EndFinishTime.HasValue, x => x.FinishTime <= input.EndFinishTime) | 
 |  |  | 
 |  |  |                                 RefundCheckRemark = a.RefundCheckRemark, | 
 |  |  |                                 RefundApplyRemark = a.RefundApplyRemark, | 
 |  |  |                                 RefundTime = a.RefundTime, | 
 |  |  |                                 ChannelName = b.ChannlesName | 
 |  |  |                                 ChannelName = b.ChannlesName, | 
 |  |  |                                 ActualRechargeAmount = a.ActualRechargeAmount, | 
 |  |  |                                 PlatformDeductionAmount = a.PlatformDeductionAmount, | 
 |  |  |                                 ACOOLYStatus = a.ACOOLYStatus, | 
 |  |  |                                 LifePayRefundStatus = a.LifePayRefundStatus, | 
 |  |  |                             }).GetPageResult(input.PageModel); | 
 |  |  |  | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public async Task<LifePayOrderOutput> GetLifePayOrderDetail(string orderNo) | 
 |  |  |     { | 
 |  |  |         var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); | 
 |  |  |         var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); | 
 |  |  |         var channle = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == order.ChannelId); | 
 |  |  |         var premium = await _lifePayPremiumRepository.Where(x => x.IsDeleted == false && x.PremiumType == order.LifePayType).FirstOrDefaultAsync(); | 
 |  |  |         CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); | 
 |  |  |         var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == order.UserId); | 
 |  |  |          | 
 |  |  |         var channlesRakePrice = (order.PayAmount - (order.PlatformDeductionAmount == null ? 0 : order.PlatformDeductionAmount)) * channle.ChannlesRakeRate / 100; | 
 |  |  |         var result = new LifePayOrderOutput() | 
 |  |  |                 { | 
 |  |  |             UserName = user.Name, | 
 |  |  |             UserPhoneNumber = user.PhoneNumber, | 
 |  |  |             DiscountAmount = order.DiscountAmount, | 
 |  |  |             FinishTime = order.FinishTime, | 
 |  |  |             Id = order.Id, | 
 |  |  |             OutOrderNo = order.OutOrderNo, | 
 |  |  |             LifePayChannle = channle.ChannlesName, | 
 |  |  |             LifePayOrderStatus = order.LifePayOrderStatus, | 
 |  |  |             LifePayOrderType = order.LifePayOrderType, | 
 |  |  |             LifePayType = order.LifePayType, | 
 |  |  |             OrderNo = order.OrderNo, | 
 |  |  |             PayAmount = order.PayAmount, | 
 |  |  |             RechargeAmount = order.RechargeAmount, | 
 |  |  |             PayStatus = order.PayStatus, | 
 |  |  |             PayTime = order.PayTime, | 
 |  |  |             OrderParamDetailJsonStr = order.OrderParamDetailJsonStr, | 
 |  |  |             RefundCredentialsImgUrl = order.RefundCredentialsImgUrl.GetOssPath(), | 
 |  |  |             CreationTime = order.CreationTime, | 
 |  |  |             RefundCheckRemark = order.RefundCheckRemark, | 
 |  |  |             RefundApplyRemark = order.RefundApplyRemark, | 
 |  |  |             RefundTime = order.RefundTime, | 
 |  |  |             ACOOLYOrderNo = order.ACOOLYOrderNo, | 
 |  |  |             LifePayRefundStatus = order.LifePayRefundStatus, | 
 |  |  |             ActualRechargeAmount = order.ActualRechargeAmount, | 
 |  |  |             RefundPrice = order.RefundPrice, | 
 |  |  |             PlatformRate = platformRate.Rate, | 
 |  |  |             PlatformPrice = order.PlatformDeductionAmount, | 
 |  |  |             ChannleRate = channle.ChannlesRate, | 
 |  |  |             ChannlesRakeRate = channle.ChannlesRakeRate, | 
 |  |  |             ChannlesRakePrice = channlesRakePrice.HasValue ? 0 : Math.Round(channlesRakePrice.Value, 2), | 
 |  |  |             PremiumRate = premium == null ? 0 : premium.Rate, | 
 |  |  |             PremiumPrice = premium == null ? 0 : Math.Round(order.PayAmount * premium.Rate, 2), | 
 |  |  |             Profit = (order.PayAmount - order.PlatformDeductionAmount) * (1.00m - channle.ChannlesRakeRate / 100) - (premium == null ? 0 : Math.Round(order.PayAmount * premium.Rate, 2)) | 
 |  |  |         }; | 
 |  |  |  | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public async Task<LifePayRefundOrderOutput> GetLifePayRefundOrderDetail(string orderNo) | 
 |  |  |     { | 
 |  |  |         var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); | 
 |  |  |         var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); | 
 |  |  |         var channle = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == order.ChannelId); | 
 |  |  |         var premium = await _lifePayPremiumRepository.Where(x => x.IsDeleted == false && x.PremiumType == order.LifePayType).FirstOrDefaultAsync(); | 
 |  |  |         CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); | 
 |  |  |         var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == order.UserId); | 
 |  |  |  | 
 |  |  |         var channlesRakePrice = (order.PayAmount - (order.PlatformDeductionAmount == null ? 0 : order.PlatformDeductionAmount)) * channle.ChannlesRakeRate / 100; | 
 |  |  |         var result = new LifePayRefundOrderOutput() | 
 |  |  |         { | 
 |  |  |             UserName = user.Name, | 
 |  |  |             UserPhoneNumber = user.PhoneNumber, | 
 |  |  |             DiscountAmount = order.DiscountAmount, | 
 |  |  |             FinishTime = order.FinishTime, | 
 |  |  |             Id = order.Id, | 
 |  |  |             OutOrderNo = order.OutOrderNo, | 
 |  |  |             LifePayChannle = channle.ChannlesName, | 
 |  |  |             LifePayOrderStatus = order.LifePayOrderStatus, | 
 |  |  |             LifePayOrderType = order.LifePayOrderType, | 
 |  |  |             LifePayType = order.LifePayType, | 
 |  |  |             OrderNo = order.OrderNo, | 
 |  |  |             PayAmount = order.PayAmount, | 
 |  |  |             RechargeAmount = order.RechargeAmount, | 
 |  |  |             PayStatus = order.PayStatus, | 
 |  |  |             PayTime = order.PayTime, | 
 |  |  |             RefundCredentialsImgUrl = order.RefundCredentialsImgUrl.GetOssPath(), | 
 |  |  |             CreationTime = order.CreationTime, | 
 |  |  |             RefundCheckRemark = order.RefundCheckRemark, | 
 |  |  |             RefundApplyRemark = order.RefundApplyRemark, | 
 |  |  |             RefundTime = order.RefundTime, | 
 |  |  |             ACOOLYOrderNo = order.ACOOLYOrderNo, | 
 |  |  |             LifePayRefundStatus = order.LifePayRefundStatus, | 
 |  |  |             ActualRechargeAmount = order.ActualRechargeAmount, | 
 |  |  |             RefundPrice = order.RefundPrice, | 
 |  |  |         }; | 
 |  |  |  | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  | 
 |  |  |  | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /// <summary> | 
 |  |  |     /// 根据订单号获取支付状态 | 
 |  |  | 
 |  |  |  | 
 |  |  |         var orderInput = new CreateLifePayOrderInput | 
 |  |  |         { | 
 |  |  |             OrderNo = CreateOrderNo(), | 
 |  |  |             OrderNo = channle.ChannlesNum + CreateOrderNo(), | 
 |  |  |             LifePayOrderStatus = LifePayOrderStatusEnum.待确认, | 
 |  |  |             LifePayOrderType = LifePayOrderTypeEnum.话费订单, | 
 |  |  |             //LifePayType = input.LifePayType, | 
 |  |  | 
 |  |  |  | 
 |  |  |         var orderInput = new CreateLifePayOrderInput | 
 |  |  |         { | 
 |  |  |             OrderNo = CreateOrderNo(), | 
 |  |  |             OrderNo = channle.ChannlesNum + CreateOrderNo(), | 
 |  |  |             LifePayOrderStatus = LifePayOrderStatusEnum.待确认, | 
 |  |  |             LifePayOrderType = LifePayOrderTypeEnum.电费订单, | 
 |  |  |             // LifePayType = input.LifePayType, | 
 |  |  | 
 |  |  |  | 
 |  |  |         var orderInput = new CreateLifePayOrderInput | 
 |  |  |         { | 
 |  |  |             OrderNo = CreateOrderNo(), | 
 |  |  |             OrderNo = channle.ChannlesNum + CreateOrderNo(), | 
 |  |  |             LifePayOrderStatus = LifePayOrderStatusEnum.待确认, | 
 |  |  |             LifePayOrderType = LifePayOrderTypeEnum.燃气订单, | 
 |  |  |             // LifePayType = input.LifePayType, | 
 |  |  | 
 |  |  |                 OpenId = openid | 
 |  |  |             } | 
 |  |  |         }; | 
 |  |  |         Logger.LogError("调用请求:" + req.ToJson()); | 
 |  |  |         var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); | 
 |  |  |         string nonce = Guid.NewGuid().ToString(); | 
 |  |  |  | 
 |  |  |         var res = await _wxPayApi.PayTransactionsJsAPI(req); | 
 |  |  |         Logger.LogError("调用结果:" + res.ToJson()); | 
 |  |  |         string package = "prepay_id=" + res.PrepayId; | 
 |  |  |         ModelPaymentMiniPay info = new ModelPaymentMiniPay(); | 
 |  |  |         if (res != null) | 
 |  |  | 
 |  |  |     /// <param name="orderNo"></param> | 
 |  |  |     /// <param name="outOrderNo"></param> | 
 |  |  |     /// <returns></returns> | 
 |  |  |     public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status) | 
 |  |  |     public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status, ACOOLYStatusEnum acoolyStatus, decimal payAmount) | 
 |  |  |     { | 
 |  |  |         var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); | 
 |  |  |         CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); | 
 |  |  | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         order.LifePayOrderStatus = status; | 
 |  |  |         order.ACOOLYStatus = acoolyStatus; | 
 |  |  |         order.PlatformDeductionAmount = payAmount; | 
 |  |  |         if (acoolyOrderNo.IsNotNullOrEmpty()) | 
 |  |  |         { | 
 |  |  |             order.ACOOLYOrderNo = acoolyOrderNo; | 
 |  |  | 
 |  |  |         { | 
 |  |  |             order.PayStatus = LifePayStatusEnum.待退款; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         await _lifePayOrderRepository.UpdateAsync(order); | 
 |  |  |     } | 
 |  |  | 
 |  |  |             throw new UserFriendlyException("当前订单状态无法退款"); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         /// TODO 退款请求完成后如何操作 | 
 |  |  |         /// var refundResult = await WxPayDomesticRefunds(order.OrderNo, order.RefundApplyRemark, Convert.ToInt32(order.PayAmount * 100), Convert.ToInt32(order.PayAmount * 100)); | 
 |  |  |         var outRefundNo = order.ChannelId + CreateRefundOrderNo(); | 
 |  |  |         order.RefundOrderNo = outRefundNo; | 
 |  |  |         switch (order.LifePayType) | 
 |  |  |         { | 
 |  |  |             case LifePayTypeEnum.WxPay: | 
 |  |  |                 var wxRefundResult = await WxPayDomesticRefunds(order.OrderNo, outRefundNo,order.RefundApplyRemark, Convert.ToInt32(order.PayAmount * 100), Convert.ToInt32(order.PayAmount * 100)); | 
 |  |  |                 if (wxRefundResult.Status == "SUCCESS") | 
 |  |  |                 { | 
 |  |  |                     order.PayStatus = LifePayStatusEnum.已退款; | 
 |  |  |                     order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; | 
 |  |  |                     order.LifePayRefundStatus = LifePayRefundStatusEnum.已退款; | 
 |  |  |                 } | 
 |  |  |                 else if (wxRefundResult.Status == "PROCESSING") | 
 |  |  |                 { | 
 |  |  |                     order.PayStatus = LifePayStatusEnum.退款中; | 
 |  |  |                     order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; | 
 |  |  |                     order.LifePayRefundStatus = LifePayRefundStatusEnum.退款中; | 
 |  |  |                 } | 
 |  |  |                 else | 
 |  |  |                 { | 
 |  |  |                     order.PayStatus = LifePayStatusEnum.待退款; | 
 |  |  |                     order.LifePayOrderStatus = LifePayOrderStatusEnum.退款失败; | 
 |  |  |                     order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款; | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |         order.PayStatus = LifePayStatusEnum.已退款; | 
 |  |  |         order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; | 
 |  |  |                 break; | 
 |  |  |             case LifePayTypeEnum.AliPay: | 
 |  |  |                 var aliRefundResult = await AliTradeRefund(new AlipayTradeRefundRequest() { OutTradeNo = order.OrderNo, RefundAmount = order.PayAmount.ToString() }); | 
 |  |  |                 if (aliRefundResult.Code != AlipayResultCode.Success) | 
 |  |  |                 { | 
 |  |  |                     throw new UserFriendlyException("退款失败"); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 order.PayStatus = LifePayStatusEnum.已退款; | 
 |  |  |                 order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; | 
 |  |  |                 break; | 
 |  |  |             default: throw new UserFriendlyException("退款失败"); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         order.RefundCredentialsImgUrl = input.RefundCredentialsImgUrl; | 
 |  |  |         order.RefundCheckRemark = input.RefundCheckRemark; | 
 |  |  |         order.RefundTime = DateTime.Now; | 
 |  |  |         order.RefundCheckUserId = CurrentUser.Id; | 
 |  |  |         order.RefundPrice = order.PayAmount; | 
 |  |  |  | 
 |  |  |         await _lifePayOrderRepository.UpdateAsync(order); | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  |         order.LifePayOrderStatus = LifePayOrderStatusEnum.退款待审核; | 
 |  |  |         order.RefundApplyRemark = input.RefundApplyRemark; | 
 |  |  |         order.RefundTime = DateTime.Now; | 
 |  |  |         order.RefundApplyTime = DateTime.Now; | 
 |  |  |  | 
 |  |  |         await _lifePayOrderRepository.UpdateAsync(order); | 
 |  |  |     } | 
 |  |  | 
 |  |  |     /// <param name="total"></param> | 
 |  |  |     /// <param name="currency"></param> | 
 |  |  |     /// <returns></returns> | 
 |  |  |     public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(string outTradeNo, string reason, int refund, int total, string currency = "CNY") | 
 |  |  |     public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(string outTradeNo,string outRefundNo, string reason, int refund, int total, string currency = "CNY") | 
 |  |  |     { | 
 |  |  |         WxPayDomesticRefundsRequest req = new WxPayDomesticRefundsRequest | 
 |  |  |         { | 
 |  |  |             OutTradeNo = outTradeNo, | 
 |  |  |             OutRefundNo = CreateRefundOrderNo(), | 
 |  |  |             OutRefundNo = outRefundNo, | 
 |  |  |             Reason = reason, | 
 |  |  |             Amount = new Model_WxPayDomesticRefunds_Amount | 
 |  |  |             { | 
 |  |  | 
 |  |  |         return res; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     private async Task<AlipayTradeRefundResponse> AliTradeRefund(AlipayTradeRefundRequest input) | 
 |  |  |     { | 
 |  |  |         return await _aliPayApi.TradeRefund(input); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public async Task<int> AddUpdateUserAccount(AddUpdateUserAccountInput input) | 
 |  |  |     { | 
 |  |  | 
 |  |  |     private (decimal PayAmont, decimal DiscountAmount, decimal RechargeAmount) CalculateAmount(decimal amount, decimal rate) | 
 |  |  |     { | 
 |  |  |         /// 正常支付 | 
 |  |  |         var payAmount = decimal.Round(amount * rate / 100, 2, MidpointRounding.AwayFromZero); | 
 |  |  |         //var payAmount = decimal.Round(amount * rate / 100, 2, MidpointRounding.AwayFromZero); | 
 |  |  |  | 
 |  |  |         /// 1分钱支付 | 
 |  |  |         //decimal payAmount = 0.01m; | 
 |  |  |         decimal payAmount = 0.01m; | 
 |  |  |  | 
 |  |  |         CheckExtensions.IfTrueThrowUserFriendlyException(payAmount < 0.01m, "支付金额错误"); | 
 |  |  |  | 
 |  |  | 
 |  |  |         CheckExtensions.IfTrueThrowUserFriendlyException(amount <= 0, | 
 |  |  |                                                          CustomeErrorMessage.SometingMustSometing, | 
 |  |  |                                                          "获取支付二维码时金额", "大于0"); | 
 |  |  |  | 
 |  |  |         var res = await _wxPayApi.PayTransactionsH5(new PayTransactionsNativeH5 | 
 |  |  |         { | 
 |  |  |             Appid = _wxPayOptions.AppID, | 
 |  |  | 
 |  |  |  | 
 |  |  |         return res.QrCode; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /// <summary> | 
 |  |  |     /// 构造待签名字符串 | 
 |  |  |     /// </summary> |