using DynamicQuery.Net.Dto.Input; using LifePayment.Application.Contracts; using LifePayment.Domain; using LifePayment.Domain.Models; using LifePayment.Domain.Shared; using MailKit.Search; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Nest; using Newtonsoft.Json; using NPOI.OpenXmlFormats.Dml.Chart; using NPOI.SS.Formula.Functions; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; 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; namespace LifePayment.Application; public class LifePayService : ApplicationService, ILifePayService { private readonly IDistributedEventBus _distributedEventBus; private readonly ILogger _logger; private readonly IRepository _lifePayRateRepository; private readonly IRepository _lifePayOrderRepository; private readonly IRepository _lifePayUserRepository; private readonly IRepository _lifePayChannlesRep; private readonly IRepository _lifePayAccount; private readonly IDataFilter dataFilter; private readonly IAliPayApi _aliPayApi; private readonly IWxPayApi _wxPayApi; private readonly WxPayOption _wxPayOptions; private readonly IACOOLYManager _aCOOLYManager; public LifePayService(IDistributedEventBus distributedEventBus, ILogger logger, IACOOLYManager aCOOLYManager, IRepository lifePayRateRepository, IRepository lifePayOrderRepository, IRepository lifePayUserRepository, IAliPayApi aliPayApi, IWxPayApi wxPayApi, IOptions wxPayOptions, IRepository lifePayChannlesRep, IRepository lifePayAccount, IDataFilter dataFilter) { _logger = logger; _aCOOLYManager = aCOOLYManager; _lifePayRateRepository = lifePayRateRepository; _lifePayOrderRepository = lifePayOrderRepository; _lifePayUserRepository = lifePayUserRepository; _aliPayApi = aliPayApi; _wxPayApi = wxPayApi; _wxPayOptions = wxPayOptions.Value; _distributedEventBus = distributedEventBus; _lifePayChannlesRep = lifePayChannlesRep; _lifePayAccount = lifePayAccount; this.dataFilter = dataFilter; } #region 查询 /// /// 获取电费面值 /// /// /// public async Task GetElectricParValue() { return await _aCOOLYManager.ElectricParValue(new ACOOLYRequestBaseInput()); } /// /// 获取电费充值区域 /// /// public async Task GetElectricSupportArea() { return await _aCOOLYManager.GetElectricSupportArea(new ACOOLYRequestBaseInput()); } /// /// 获取话费面值 /// /// /// public async Task GetPhoneParValue() { return await _aCOOLYManager.PhoneParValue(new ACOOLYRequestBaseInput()); } /// /// 获取话费面值 /// /// /// public async Task GetGasParValue() { return await _aCOOLYManager.GasParValue(new GasParValueRequestInput()); } /// /// 获取燃气支持商户 /// /// public async Task GetGasOrgType() { return await _aCOOLYManager.GasOrgType(new GasOrgTypeRequestInput()); } /// /// 获取折扣 /// /// public async Task> GetRate() { return await _lifePayRateRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayRateListOutput() { Id = x.Id, Rate = x.Rate, RateType = x.RateType }) .ToListAsync(); } /// /// 获取用户分页数据 /// /// /// public async Task> GetUserPage(PageInput input) { return await _lifePayUserRepository.Select(x => new UserListOutput() { Id = x.Id, PhoneNumber = x.PhoneNumber, CreationTime = x.CreationTime, LastLoginTime = x.LastLoginTime }) .GetPageResult(input.PageModel); } /// /// 获取用户户号分页数据 /// /// /// public async Task> GetAccountPage(QueryUserAccountListInput input) { using (dataFilter.Disable()) { 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); } } /// /// 获取订单分页数据 /// /// /// public async Task> GetLifePayOrderPage(QueryLifePayOrderListInput input) { 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) .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; } /// /// 获取我的订单分页数据 /// /// /// public async Task> GetUserLifePayOrderPage(QueryLifePayOrderListInput input) { if (!input.UserId.HasValue) { return new PageOutput(); } return await _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.UserId.HasValue, x => x.UserId == input.UserId.Value) .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayOrderType == input.LifePayOrderType) .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, }) .GetPageResult(input.PageModel); } public async Task 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; } /// /// 根据订单号获取支付状态 /// /// /// public async Task GetPayStatusByOrderNo(string orderNo) { return await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo) .Select(x => x.PayStatus) .FirstOrDefaultAsync(); } public async Task> GetLifePayChannlesPage(PageInput input) { return await GetLifePayChannlesListFilter().GetPageResult(input.PageModel); } public async Task> GetLifePayChannlesAllList() { return await GetLifePayChannlesListFilter().Where(x => x.Status == LifePayChannelsStatsEnum.启用).ToListAsync(); } public async Task 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 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 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> GetUserAccountList(QueryUserAccountListInput input) { if (!input.UserId.HasValue) { return new PageOutput(); } 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> GetUserAccountAllList(QueryUserAccountAllListInput input) { if (!input.UserId.HasValue) { return new List(); } 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 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> 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 操作 /// /// 创建生活缴费话费订单 /// /// /// public async Task CreateLifePayPhoneOrder(CreateLifePayOrderInput 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(), "未配置折扣"); 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); var result = new CreateLifePayOrderOutput() { OrderNo = orderInput.OrderNo, }; return result; } /// /// 创建生活缴费电费订单 /// /// /// public async Task CreateLifePayElectricOrder(CreateLifePayOrderInput 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); var result = new CreateLifePayOrderOutput() { OrderNo = orderInput.OrderNo, }; return result; } /// /// 创建生活缴费燃气订单 /// /// /// public async Task CreateLifePayGasOrder(CreateLifePayOrderInput 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); var result = new CreateLifePayOrderOutput() { OrderNo = orderInput.OrderNo, }; return result; } /// /// 设置生活缴费支付类型 /// /// /// public async Task SetLifePayOrderPayType(SetLifePayOrderPayTypeInput input, string ip) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == input.OrderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(order.LifePayType.HasValue, "当前订单已选择支付类型"); order.LifePayType = input.LifePayType; await _lifePayOrderRepository.UpdateAsync(order); var desc = "生活缴费-"; switch (order.LifePayOrderType) { case LifePayOrderTypeEnum.话费订单: desc += "话费"; break; case LifePayOrderTypeEnum.电费订单: desc += "电费"; break; default: break; } #if DEBUG //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); #else //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); #endif return payUrl; } /// /// 设置生活缴费支付类型 /// /// /// public async Task GetPayOrderForJsAPI(GetPayOrderForJsAPIInput input, string ip) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == input.OrderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(order.LifePayType.HasValue, "当前订单已选择支付类型"); order.LifePayType = input.LifePayType; await _lifePayOrderRepository.UpdateAsync(order); var desc = "生活缴费-"; switch (order.LifePayOrderType) { case LifePayOrderTypeEnum.话费订单: desc += "话费"; break; case LifePayOrderTypeEnum.电费订单: desc += "电费"; break; case LifePayOrderTypeEnum.燃气订单: desc += "燃气"; break; default: break; } //var result = await PayTransactionsJsAPI(input.OpenId, input.Attach, 0.01m, input.OrderNo, desc); //return result; // 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); } /// /// 创建生活缴费订单 /// /// /// public async Task CreateLifePayOrder(CreateLifePayOrderInput input) { CheckExtensions.IfTrueThrowUserFriendlyException(input.RechargeAmount < 0.01m || input.PayAmount < 0.01m || input.DiscountAmount < 0, "订单金额错误"); var entity = ObjectMapper.Map(input); await _lifePayOrderRepository.InsertAsync(entity); } /// /// 创建ACOOLY话费订单 /// /// /// public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYPhoneOrder(LifePhoneData input, string orderNo) { var requestInput = new ConfirmPhoneOrderRequestInput() { IspCode = input.IspCode, ParValue = input.ParValue, Phone = input.Phone, OutOrderNo = orderNo, Name = input.Name }; var result = await _aCOOLYManager.ConfirmPhoneOrder(requestInput); #if DEBUG _logger.LogInformation($"CreateACOOLYPhoneOrder:{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.PhoneChargeOrder.BusiOrderNo); } /// /// 创建ACOOLY电费订单 /// /// /// public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYElectricOrder(LifeElectricData input, string orderNo) { var requestInput = new ConfirmElectricOrderRequestInput() { City = input.City, ElectricAccount = input.ElectricAccount, ElectricAccountType = input.ElectricAccountType, ElectricType = input.ElectricType, ParValue = input.ParValue, Province = input.Province, SixID = input.SixID, OutOrderNo = orderNo }; var result = await _aCOOLYManager.ConfirmElectricOrder(requestInput); #if DEBUG _logger.LogInformation($"CreateACOOLYElectricOrder:{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.ElectricChargeOrder.BusiOrderNo); } /// /// 创建ACOOLY燃气订单 /// /// /// public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYGasOrder(LifeGasData input, string orderNo) { 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 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 = appId, Mchid = _wxPayOptions.Mchid, Attach = order_guid, Description = description, OutTradeNo = outTradeNo, Amount = new Model_MiniPay_Amount { Total = Convert.ToInt32(100 * amount), Currency = "CNY" }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxRechargeNotifySectionUrl}", Payer = new Model_MiniPay_Payer { OpenId = openid } }; var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); string nonce = Guid.NewGuid().ToString(); var res = await _wxPayApi.PayTransactionsJsAPI(req); string package = "prepay_id=" + res.PrepayId; ModelPaymentMiniPay info = new ModelPaymentMiniPay(); if (res != null) { string paytext = BuildSignByPay(appId, timestamp, nonce, package); string paysign = _wxPayApi.GeneratePaySignByKey(paytext); info.Timestamp = timestamp.ToString(); info.NonceStr = nonce; info.Package = package; info.SignType = "RSA"; info.PaySign = paysign; info.TimeExpire = time_expire; } return info; } /// /// 构造签名串 /// /// 小程序的AppID /// 时间戳 /// 随机字符串 /// package值 /// 签名串 public string BuildSignByPay(string appId, long timestamp, string nonceStr, string package) { string format = $"{appId}\n{timestamp}\n{nonceStr}\n{package}\n"; return format; } /// /// 支付成功回调处理 /// /// /// /// public async Task LifePaySuccessHandler(string orderNo, string outOrderNo) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.PayStatus == LifePayStatusEnum.已支付) { return; } order.PayStatus = LifePayStatusEnum.已支付; order.PayTime = DateTime.Now; order.OutOrderNo = outOrderNo; try { var result = (Code: "Fail", RequestNo: "", ACOOLYOrderNo: ""); switch (order.LifePayOrderType) { case LifePayOrderTypeEnum.话费订单: result = await CreateACOOLYPhoneOrder(JsonConvert.DeserializeObject(order.OrderParamDetailJsonStr), order.OrderNo); break; case LifePayOrderTypeEnum.电费订单: result = await CreateACOOLYElectricOrder(JsonConvert.DeserializeObject(order.OrderParamDetailJsonStr), order.OrderNo); break; case LifePayOrderTypeEnum.燃气订单: result = await CreateACOOLYGasOrder(JsonConvert.DeserializeObject(order.OrderParamDetailJsonStr), order.OrderNo); break; default: break; } order.LifePayOrderStatus = LifePayOrderStatusEnum.待确认; //SetOrderStatus(order, result.Code); order.OutRequestNo = result.RequestNo.IsNullOrEmpty() ? null : result.RequestNo; order.ACOOLYOrderNo = result.ACOOLYOrderNo.IsNullOrEmpty() ? null : result.ACOOLYOrderNo; } catch (Exception ex) { _logger.LogError(ex, "处理生活缴费支付成功回调时异常"); order.LifePayOrderStatus = LifePayOrderStatusEnum.已失败; order.PayStatus = LifePayStatusEnum.待退款; } _logger.LogError("生活缴费订单状态:" + order.LifePayOrderStatus.ToString()); await _lifePayOrderRepository.UpdateAsync(order); } /// /// ACOOLYO订单通知处理 /// /// /// /// public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成) { return; } order.LifePayOrderStatus = status; if (acoolyOrderNo.IsNotNullOrEmpty()) { order.ACOOLYOrderNo = acoolyOrderNo; } if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成) { order.FinishTime = DateTime.Now; } if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已失败 && order.PayStatus != LifePayStatusEnum.已退款) { order.PayStatus = LifePayStatusEnum.待退款; } await _lifePayOrderRepository.UpdateAsync(order); } /// /// 退款生活缴费订单 /// /// /// /// public async Task RefundLifePayOrder(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.退款待审核) { 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); #region 记录日志 await PublishLifePayOrderHistoryEvent("退款", "退款", order.Id); #endregion } /// /// 用户发起生活缴费退款 /// /// /// /// 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 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 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; } /// /// 用户删除户号信息 /// /// /// public async Task 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; } /// /// 退款驳回 /// /// /// /// 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(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 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 input) { CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate <= 0).Any(), "折扣不得小于等于0"); var baseRate = input.FirstOrDefault(r => r.RateType == LifePayRateTypeEnum.供应商折扣价)?.Rate; var listData = new List(); 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); } } #endregion #region 私有 private string CreateOrderNo() { 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 / 100, 2, MidpointRounding.AwayFromZero); /// 1分钱支付 //decimal payAmount = 0.01m; CheckExtensions.IfTrueThrowUserFriendlyException(payAmount < 0.01m, "支付金额错误"); return (payAmount, amount - payAmount, amount); } private void SetOrderStatus(LifePayOrder order, string code) { switch (code) { case ACOOLYConstant.Code.SUCCESS: order.LifePayOrderStatus = LifePayOrderStatusEnum.已完成; order.FinishTime = DateTime.Now; break; case ACOOLYConstant.Code.PROCESSING: order.LifePayOrderStatus = LifePayOrderStatusEnum.待确认; break; default: break; } } /// /// 记录相关的操作历史 /// /// /// private async Task PublishLifePayOrderHistoryEvent(string operateContent, string operateName, Guid relationId, int? tableType = TableType.LifePayOrder) { var recordEto = new RecordOperateHistoryEto { CreatorName = CurrentUser.Name, OperateContent = operateContent, OperateName = operateName, RelationId = relationId, TableType = tableType }; await _distributedEventBus.PublishAsync(recordEto, false); } /// /// 获取支付二维码 /// /// /// /// /// /// /// public async Task GetPayQRCode(LifePayTypeEnum payType, string outTradeNo, string description, decimal amount, string ip, string h5Type) { var codeUrl = string.Empty; switch (payType) { case LifePayTypeEnum.AliPay: codeUrl = await GetAliPayQRCode(outTradeNo, description, amount); break; case LifePayTypeEnum.WxPay: codeUrl = await GetWxPayQRCode(outTradeNo, description, amount); //native // codeUrl = await GetWxPayH5Url(outTradeNo, description, amount, ip, h5Type); //h5 break; default: throw new UserFriendlyException(string.Format(CustomeErrorMessage.NotImplementedWhenSometing, "获取支付二维码")); } return codeUrl; } /// /// 获取微信支付二维码 /// /// /// /// /// /// private async Task GetWxPayQRCode(string outTradeNo, string description, decimal amount) { CheckExtensions.IfTrueThrowUserFriendlyException(amount <= 0, CustomeErrorMessage.SometingMustSometing, "获取支付二维码时金额", "大于0"); var res = await _wxPayApi.PayTransactionsNative(new PayTransactionsNativeInput { Appid = _wxPayOptions.AppID, Mchid = _wxPayOptions.Mchid, Description = description, OutTradeNo = outTradeNo, Amount = new PayAmount { Total = Convert.ToInt32(100 * amount), }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxRechargeNotifySectionUrl}", }); if (res == null || res.CodeUrl.IsNullOrEmpty()) { _logger.LogError($"获取微信支付二维码异常:{(res == null ? "返回参数为空" : $"{res.Code} --{res.Message}")}"); throw new UserFriendlyException(string.Format(CustomeErrorMessage.SometingError, "获取支付二维码时")); } return res.CodeUrl; } /// /// 获取微信支付二维码 /// /// /// /// /// /// private async Task GetWxPayH5Url(string outTradeNo, string description, decimal amount, string ip, string h5Type) { CheckExtensions.IfTrueThrowUserFriendlyException(amount <= 0, CustomeErrorMessage.SometingMustSometing, "获取支付二维码时金额", "大于0"); var res = await _wxPayApi.PayTransactionsH5(new PayTransactionsNativeH5 { Appid = _wxPayOptions.AppID, Mchid = _wxPayOptions.Mchid, Description = description, OutTradeNo = outTradeNo, Amount = new PayAmount { Total = Convert.ToInt32(100 * amount), }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxRechargeNotifySectionUrl}", SceneInfo = new H5SceneInfo() { PayerClientIp = ip, H5Info = new H5Info() { Type = h5Type } } }); if (res == null || res.H5Url.IsNullOrEmpty()) { _logger.LogError($"获取微信支付Url异常:{(res == null ? "返回参数为空" : $"{res.Code} --{res.Message}")}"); throw new UserFriendlyException(string.Format(CustomeErrorMessage.SometingError, "获取支付Url时")); } return res.H5Url; } /// /// 获取支付宝二维码 /// /// /// /// /// /// private async Task GetAliPayQRCode(string outTradeNo, string description, decimal amount) { CheckExtensions.IfTrueThrowUserFriendlyException(amount < 0.01M, CustomeErrorMessage.SometingMustSometing, "获取支付二维码时金额", "大于0.01"); var res = await _aliPayApi.GetAliPayQRCode(new GetPayQrCodeInput { Subject = description, OutTradeNo = outTradeNo, TotalAmount = amount, }); if (res == null || res.QrCode.IsNullOrEmpty()) { _logger.LogError($"获取支付宝支付二维码异常:{(res == null ? "返回参数为空" : $"{res.Code} --{res.Msg}")}"); throw new UserFriendlyException(string.Format(CustomeErrorMessage.SometingError, "获取支付二维码时")); } return res.QrCode; } /// /// 构造待签名字符串 /// /// HTTP请求方法 /// API接口的相对路径 /// 时间戳(秒级) /// 随机字符串 /// 请求体的JSON字符串 /// 待签名字符串 public static string BuildSignByUniOrder(string method, string uri, long timestamp, string nonce, string body) { string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n"; return message; } private async Task> 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; } private IQueryable GetLifePayChannlesListFilter() { return _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, }); } #endregion }