sunpengfei
2025-06-16 e0f2b29f3349d43e7f4222e079c54ba9cc4b6ee1
LifePayment/LifePayment.Application/LifePay/LifePayService.cs
@@ -8,18 +8,22 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus.Distributed;
using Z.EntityFramework.Plus;
using ZeroD.Util;
using ZeroD.Util.Fadd;
using static LifePayment.Domain.Shared.LifePaymentConstant;
namespace LifePayment.Application;
@@ -42,6 +46,7 @@
    private readonly ILifePayOrderService _lifePayOrderService;
    private readonly IDataFilter dataFilter;
    private readonly IChannelFilter _channelFilter;
    private readonly IAbpDistributedLock distributedLock;
    private readonly IAliPayApi _aliPayApi;
    private readonly IAlipayInterfaceManager _alipayInterfaceManager;
    private readonly IWxPayApi _wxPayApi;
@@ -49,10 +54,12 @@
    private readonly InitSetting _initSettingOptions;
    private readonly IACOOLYManager _aCOOLYManager;
    private readonly IRepository<LifePayPromoter, Guid> lifePayPromoterRepository;
    public LifePayService(IDistributedEventBus distributedEventBus,
                          ILogger<LifePayService> logger,
                          IACOOLYManager aCOOLYManager,
                          IRepository<LifePayPromoter, Guid> lifePayPromoterRepository,
                          IRepository<LifePayRate, Guid> lifePayRateRepository,
                          IRepository<LifePayOrder, Guid> lifePayOrderRepository,
                          IRepository<LifePayUser, Guid> lifePayUserRepository,
@@ -69,10 +76,12 @@
                          IRepository<LifePayChannles, Guid> lifePayChannlesRep,
                          IRepository<LifePayAccount, Guid> lifePayAccount,
                          IDataFilter dataFilter,
                          IChannelFilter channelFilter)
                          IChannelFilter channelFilter,
                          IAbpDistributedLock distributedLock)
    {
        _logger = logger;
        _aCOOLYManager = aCOOLYManager;
        this.lifePayPromoterRepository = lifePayPromoterRepository;
        _lifePayRateRepository = lifePayRateRepository;
        _lifePayOrderRepository = lifePayOrderRepository;
        _lifePayUserRepository = lifePayUserRepository;
@@ -90,11 +99,11 @@
        _lifePayAccount = lifePayAccount;
        this.dataFilter = dataFilter;
        _channelFilter = channelFilter;
        this.distributedLock = distributedLock;
        _operateHistory = operateHistory;
    }
    #region 查询
    /// <summary>
    /// 获取电费面值
@@ -123,6 +132,16 @@
    public async Task<PhoneParValueResponse> GetPhoneParValue()
    {
        return await _aCOOLYManager.PhoneParValue(new ACOOLYRequestBaseInput());
    }
    /// <summary>
    /// 话费订单查询
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<QueryPhoneOrderResponse> QueryPhoneOrder(QueryPhoneOrderRequestInput input)
    {
        return await _aCOOLYManager.QueryPhoneOrder(input);
    }
    /// <summary>
@@ -294,8 +313,41 @@
                                PlatformDeductionAmount = a.PlatformDeductionAmount,
                                ACOOLYStatus = a.ACOOLYStatus,
                                LifePayRefundStatus = a.LifePayRefundStatus,
                                OrderParamDetailJsonStr = a.OrderParamDetailJsonStr,
                            }).GetPageResult(input.PageModel);
        if (result != null && result.Data != null && result.Data.Count > 0)
        {
            foreach (var s in result.Data)
            {
                if (!string.IsNullOrWhiteSpace(s.OrderParamDetailJsonStr))
                {
                    if (s.LifePayOrderType == LifePayOrderTypeEnum.PhoneOrder)
                    {
                        var name = s.OrderParamDetailJsonStr.JsonToObject<LifePhoneData>()?.IspCode;
                        if (Enum.TryParse<IspCodeEnum>(name, true, out var @enum))
                        {
                            s.Operator = @enum.GetDescription();
                        }
                    }
                    else if (s.LifePayOrderType == LifePayOrderTypeEnum.ElectricOrder)
                    {
                        var name = s.OrderParamDetailJsonStr.JsonToObject<LifeElectricData>()?.ElectricType;
                        if (Enum.TryParse<ElectricTypeEnum>(name, true, out var @enum))
                        {
                            s.Operator = @enum.GetDescription();
                        }
                    }
                    else if (s.LifePayOrderType == LifePayOrderTypeEnum.GasOrder)
                    {
                        var name = s.OrderParamDetailJsonStr.JsonToObject<LifeGasData>()?.GasOrgType;
                        if (Enum.TryParse<GasOrgCodeEnum>(name, true, out var @enum))
                        {
                            s.Operator = @enum.GetDescription();
                        }
                    }
                }
            }
        }
        return result;
    }
@@ -349,6 +401,7 @@
                                RefundPrice = a.RefundPrice,
                                ChannelName = b.ChannlesName,
                                ActualRechargeAmount = a.RechargeAmount,
                                ActualReceivedAmount = a.ActualReceivedAmount,
                                PlatformDeductionAmount = a.PlatformDeductionAmount,
                                ACOOLYStatus = a.ACOOLYStatus,
                                LifePayRefundStatus = a.LifePayRefundStatus,
@@ -398,6 +451,7 @@
            s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm);
            s.RefundApplyTimeStr = !s.RefundApplyTime.HasValue ? string.Empty : s.RefundApplyTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm);
        });
        CheckExtensions.IfTrueThrowUserFriendlyException(result.IsNullOrEmpty(), "暂无数据导出");
        return result;
    }
@@ -449,6 +503,7 @@
            PremiumPrice = orderpirce.PremiumPrice,
            Profit = orderpirce.Profit,
            RefundOrderNo = order.RefundOrderNo,
            ActualReceivedAmount = order.ActualReceivedAmount
        };
        return result;
@@ -752,7 +807,8 @@
            ACOOLYStatus = x.ACOOLYStatus,
            //RefundApplyRemark = x.RefundApplyRemark,
            ChannelName = x.ChannelName,
            PlatformPrice = x.PlatformDeductionAmount.HasValue ? x.PlatformDeductionAmount.Value : 0.00m
            PlatformPrice = x.PlatformDeductionAmount.HasValue ? x.PlatformDeductionAmount.Value : 0.00m,
            OrderParamDetailJsonStr = x.OrderParamDetailJsonStr,
        }).OrderByDescending(r => r.CreationTime).ToListAsync();
        var i = 0;
        result.ForEach(s =>
@@ -770,9 +826,112 @@
            s.ACOOLYStatusStr = s.ACOOLYStatus.GetDescription();
            s.LifePayOrderStatusStr = s.LifePayOrderStatus.GetDescription();
            s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmmss);
            if (!string.IsNullOrWhiteSpace(s.OrderParamDetailJsonStr))
            {
                if (s.LifePayOrderType == LifePayOrderTypeEnum.PhoneOrder)
                {
                    var name = s.OrderParamDetailJsonStr.JsonToObject<LifePhoneData>()?.IspCode;
                    if (Enum.TryParse<IspCodeEnum>(name, true, out var @enum))
                    {
                        s.Operator = @enum.GetDescription();
                    }
                }
                else if (s.LifePayOrderType == LifePayOrderTypeEnum.ElectricOrder)
                {
                    var name = s.OrderParamDetailJsonStr.JsonToObject<LifeElectricData>()?.ElectricType;
                    if (Enum.TryParse<ElectricTypeEnum>(name, true, out var @enum))
                    {
                        s.Operator = @enum.GetDescription();
                    }
                }
                else if (s.LifePayOrderType == LifePayOrderTypeEnum.GasOrder)
                {
                    var name = s.OrderParamDetailJsonStr.JsonToObject<LifeGasData>()?.GasOrgType;
                    if (Enum.TryParse<GasOrgCodeEnum>(name, true, out var @enum))
                    {
                        s.Operator = @enum.GetDescription();
                    }
                }
            }
        });
        CheckExtensions.IfTrueThrowUserFriendlyException(result.IsNullOrEmpty(), "暂无数据导出");
        return result;
    }
    public async Task<List<LifePayOrderListTemplateForChannle>> GetLifePayOrderPageExportForChannle(QueryLifePayOrderListInput input)
    {
        var result = await (await GetLifePayOrderListFilter(input)).Select(x => new LifePayOrderListTemplateForChannle
        {
            DiscountAmount = x.DiscountAmount,
            FinishTime = x.FinishTime,
            LifePayOrderStatus = x.LifePayOrderStatus,
            LifePayOrderType = x.LifePayOrderType,
            LifePayType = x.LifePayType,
            OrderNo = x.OrderNo,
            PayAmount = x.PayAmount,
            ActualRechargeAmount = x.RechargeAmount,
            PhoneNumber = x.PhoneNumber,
            RechargeAmount = x.RechargeAmount,
            OutOrderNo = x.OutOrderNo,
            PayStatus = x.PayStatus,
            PayTime = x.PayTime,
            ACOOLYOrderNo = x.ACOOLYOrderNo,
            CreationTime = x.CreationTime,
            LifePayRefundStatus = x.LifePayRefundStatus,
            ACOOLYStatus = x.ACOOLYStatus,
            //RefundApplyRemark = x.RefundApplyRemark,
            ChannelName = x.ChannelName,
            PlatformPrice = x.PlatformDeductionAmount.HasValue ? x.PlatformDeductionAmount.Value : 0.00m,
            OrderParamDetailJsonStr = x.OrderParamDetailJsonStr,
        }).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.yyyyMMddHHmmss);
            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.yyyyMMddHHmmss);
            s.LifePayTypeStr = s.LifePayType.GetDescription();
            s.PayStatusStr = s.PayStatus.GetDescription();
            s.ActualRechargeAmountStr = s.ActualRechargeAmount.ToString("F2");
            s.LifePayRefundStatusStr = s.LifePayRefundStatus == LifePayRefundStatusEnum.无需退款 ? "" : s.LifePayRefundStatus.GetDescription();
            s.ACOOLYStatusStr = s.ACOOLYStatus.GetDescription();
            s.LifePayOrderStatusStr = s.LifePayOrderStatus.GetDescription();
            s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmmss);
            if (!string.IsNullOrWhiteSpace(s.OrderParamDetailJsonStr))
            {
                if (s.LifePayOrderType == LifePayOrderTypeEnum.PhoneOrder)
                {
                    var name = s.OrderParamDetailJsonStr.JsonToObject<LifePhoneData>()?.IspCode;
                    if (Enum.TryParse<IspCodeEnum>(name, true, out var @enum))
                    {
                        s.Operator = @enum.GetDescription();
                    }
                }
                else if (s.LifePayOrderType == LifePayOrderTypeEnum.ElectricOrder)
                {
                    var name = s.OrderParamDetailJsonStr.JsonToObject<LifeElectricData>()?.ElectricType;
                    if (Enum.TryParse<ElectricTypeEnum>(name, true, out var @enum))
                    {
                        s.Operator = @enum.GetDescription();
                    }
                }
                else if (s.LifePayOrderType == LifePayOrderTypeEnum.GasOrder)
                {
                    var name = s.OrderParamDetailJsonStr.JsonToObject<LifeGasData>()?.GasOrgType;
                    if (Enum.TryParse<GasOrgCodeEnum>(name, true, out var @enum))
                    {
                        s.Operator = @enum.GetDescription();
                    }
                }
            }
        });
        CheckExtensions.IfTrueThrowUserFriendlyException(result.IsNullOrEmpty(), "暂无数据导出");
        return result;
    }
    public async Task<string> GetBillErceiptExport(string orderNo)
    {
        try
@@ -932,7 +1091,6 @@
        var amount = CalculateAmount(input.ProductData.ParValue, rate);
        var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价);
        var orderInput = new CreateLifePayOrderInput
        {
@@ -1289,9 +1447,10 @@
    public async Task LifePaySuccessHandler(string orderNo, string outOrderNo)
    {
        var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync();
        _logger.LogInformation($"正在处理订单:{order?.Id}-{order?.PayStatus}");
        CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在");
        if (order.PayStatus == LifePayStatusEnum.已支付)
        if (order.PayStatus != LifePayStatusEnum.未支付)
        {
            return;
        }
@@ -1317,6 +1476,7 @@
                default:
                    break;
            }
            _logger.LogInformation("已向供应商发起订单");
            order.LifePayRefundStatus = LifePayRefundStatusEnum.无需退款;
            order.LifePayOrderStatus = LifePayOrderStatusEnum.充值中;
@@ -1324,10 +1484,12 @@
            order.OutRequestNo = result.RequestNo.IsNullOrEmpty() ? null : result.RequestNo;
            order.ACOOLYOrderNo = result.ACOOLYOrderNo;
            order.ACOOLYStatus = ACOOLYStatusEnum.充值中;
            _logger.LogInformation("生活缴费订单:" + order.ToJson());
            /// 创建生活缴费消费记录
            await _lifePayOrderService.CreatLifePayConsumption(ACOOLYStatusEnum.充值中, order.OrderNo, order.ACOOLYOrderNo,
                                order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime);
            _logger.LogInformation("已插入消费记录");
        }
        catch (Exception ex)
        {
@@ -1337,7 +1499,6 @@
            order.ACOOLYStatus = ACOOLYStatusEnum.充值失败;
            order.RefundApplyRemark = ex.Message;
        }
        _logger.LogError("生活缴费订单状态:" + order.LifePayOrderStatus.ToString());
        await _lifePayOrderRepository.UpdateAsync(order);
    }
@@ -1370,61 +1531,93 @@
    /// <returns></returns>
    public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status, ACOOLYStatusEnum acoolyStatus, decimal payAmount, string refundApplyRemark, decimal? parValue = 0, decimal? actualParValue = 0)
    {
        var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync();
        CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在");
        if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成)
        await using var orderLock = await distributedLock.TryAcquireAsync($"LockKey:UpdateOrder:{orderNo}", TimeSpan.FromSeconds(60));
        _logger.LogInformation($"锁:LockKey:UpdateOrder:{orderNo} - {orderLock != null}");
        try
        {
            return;
        }
            var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync();
        // order.PlatformDeductionAmount = payAmount;
            CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在");
        if (acoolyOrderNo.IsNotNullOrEmpty())
        {
            order.ACOOLYOrderNo = acoolyOrderNo;
        }
        if (status == LifePayOrderStatusEnum.待退款)
        {
            order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款;
        }
        if (refundApplyRemark.IsNotNullOrEmpty())
        {
            order.RefundApplyRemark = refundApplyRemark;
        }
        order.LifePayOrderStatus = status;
        order.ACOOLYStatus = acoolyStatus;
        order.FinishTime = DateTime.Now;
        await _lifePayOrderRepository.UpdateAsync(order);
        if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成)
        {
            ///结算渠道佣金
            /// 毛利
            var grossProfit = order.RechargeAmount * (order.ChannleRate - order.PlatformRate) / 100;
            /// 渠道佣金  ((充值面额 * 渠道折扣比例)-(充值面额 * 平台折扣比例))* 佣金比例
            var channlesRakePrice = grossProfit * (order.ChannlesRakeRate) / 100;
            if (channlesRakePrice.HasValue)
            if (order.ACOOLYStatus.HasValue && (int)order.ACOOLYStatus > (int)acoolyStatus)
            {
                LifePayChannlesRake lifePayChannlesRake = new LifePayChannlesRake()
                {
                    OrderNo = order.OrderNo,
                    PayAmount = order.RechargeAmount ?? 0,
                    ChannlesRakeRate = order.ChannlesRakeRate ?? 0,
                    ChannlesRakePrice = channlesRakePrice ?? 0,
                    FinishTime = order.FinishTime.Value,
                    ChannelId = order.ChannelId,
                };
                await _lifePayChannlesRakeRepository.InsertAsync(lifePayChannlesRake);
                _logger.LogInformation($"订单({orderNo})由{order.ACOOLYStatus}至{acoolyStatus}失败,不可回滚状态");
                return;
            }
        }
        /// 创建生活缴费消费记录
        await _lifePayOrderService.CreatLifePayConsumption(acoolyStatus, order.OrderNo, order.ACOOLYOrderNo,
                    order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime, order.ChannleRate, parValue, actualParValue);
            if (order.LifePayOrderStatus == status && order.ACOOLYStatus == acoolyStatus)
            {
                _logger.LogInformation($"订单({orderNo})已处理该状态");
                return;
            }
            order.ActualReceivedAmount = actualParValue;
            order.PlatformDeductionAmount = Math.Round((order.ActualReceivedAmount ?? 0) * (order.PlatformRate ?? 0) / 100, 2);
            if (acoolyOrderNo.IsNotNullOrEmpty())
            {
                order.ACOOLYOrderNo = acoolyOrderNo;
            }
            if (status == LifePayOrderStatusEnum.待退款)
            {
                order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款;
            }
            if (refundApplyRemark.IsNotNullOrEmpty())
            {
                order.RefundApplyRemark = refundApplyRemark;
            }
            order.LifePayOrderStatus = status;
            order.ACOOLYStatus = acoolyStatus;
            if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成
                || order.LifePayOrderStatus == LifePayOrderStatusEnum.已退款)
            {
                order.FinishTime = DateTime.Now;
            }
            if (order.ACOOLYStatus == ACOOLYStatusEnum.已退款 || order.ACOOLYStatus == ACOOLYStatusEnum.部分充值成功)
            {
                order.RefundPrice = Math.Round((1 - ((order.ActualReceivedAmount ?? 0) / (order.RechargeAmount ?? 0))) * (order.PayAmount ?? 0), 2);
            }
            if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成)
            {
                ///结算渠道佣金
                /// 毛利
                var grossProfit = order.RechargeAmount * (order.ChannleRate - order.PlatformRate) / 100;
                /// 渠道佣金  ((充值面额 * 渠道折扣比例)-(充值面额 * 平台折扣比例))* 佣金比例
                var channlesRakePrice = grossProfit * (order.ChannlesRakeRate) / 100;
                if (channlesRakePrice.HasValue)
                {
                    LifePayChannlesRake lifePayChannlesRake = new LifePayChannlesRake()
                    {
                        OrderNo = order.OrderNo,
                        PayAmount = order.RechargeAmount ?? 0,
                        ChannlesRakeRate = order.ChannlesRakeRate ?? 0,
                        ChannlesRakePrice = channlesRakePrice ?? 0,
                        FinishTime = order.FinishTime.Value,
                        ChannelId = order.ChannelId,
                    };
                    await _lifePayChannlesRakeRepository.InsertAsync(lifePayChannlesRake);
                }
            }
            /// 创建生活缴费消费记录
            await _lifePayOrderService.CreatLifePayConsumption(acoolyStatus, order.OrderNo, order.ACOOLYOrderNo,
                        order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime, order.ChannleRate, parValue, actualParValue);
            await CurrentUnitOfWork.SaveChangesAsync();
            _logger.LogInformation("事务完成");
        }
        catch (Exception ex)
        {
            await CurrentUnitOfWork.RollbackAsync();
            _logger.LogError($"供应商回调异常:{ex.Message}", ex);
        }
    }
    /// <summary>
@@ -1505,6 +1698,8 @@
        order.RefundTime = DateTime.Now;
        order.RefundCheckUserId = CurrentUser.Id;
        order.RefundPrice = input.RefundPrice;
        order.ActualReceivedAmount = Math.Round((1 - ((order.RefundPrice ?? 0) / (order.PayAmount ?? 0))) * (order.RechargeAmount ?? 0), 2);
        order.PlatformDeductionAmount = Math.Round((order.ActualReceivedAmount ?? 0) * (order.PlatformRate ?? 0) / 100, 2);
        //await _lifePayOrderRepository.UpdateAsync(order);
@@ -1681,18 +1876,19 @@
        if (order.LifePayOrderStatus == LifePayOrderStatusEnum.待退款 || order.LifePayRefundStatus == LifePayRefundStatusEnum.待退款)
        {
            if (order.ACOOLYStatus == ACOOLYStatusEnum.已完成 || order.ACOOLYStatus == ACOOLYStatusEnum.充值成功 || order.ACOOLYStatus == ACOOLYStatusEnum.部分充值成功)
            if (order.ACOOLYStatus == ACOOLYStatusEnum.已完成 || order.ACOOLYStatus == ACOOLYStatusEnum.充值成功)
            {
                order.LifePayOrderStatus = LifePayOrderStatusEnum.已完成;
                order.LifePayRefundStatus = null;
            }
            else
            {
                order.LifePayOrderStatus = LifePayOrderStatusEnum.退款失败;
                order.LifePayOrderStatus = LifePayOrderStatusEnum.待退款;
                order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款;
            }
            order.RefundCheckRemark = input.RefundCheckRemark;
            order.RefundCheckUserId = CurrentUser.Id;
            order.LifePayRefundStatus = LifePayRefundStatusEnum.退款驳回;
            await _lifePayOrderRepository.UpdateAsync(order);
@@ -1714,13 +1910,26 @@
        {
            var dto = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.Id == input.Id.Value);
            CheckExtensions.IfTrueThrowUserFriendlyException(dto == null, "未获取到渠道折扣数据");
            if (!string.IsNullOrWhiteSpace(input.PromoterIdNumber) || !string.IsNullOrWhiteSpace(input.PromoterName))
            {
                var promoter = await lifePayPromoterRepository.FirstOrDefaultAsync(it => it.IdNumber == input.PromoterIdNumber && it.Name == input.PromoterName);
                CheckExtensions.IfTrueThrowUserFriendlyException(promoter == null, "该推广人不存在");
                dto.PromoterId = promoter.Id;
            }
            var rate = await _lifePayRateRepository.FirstOrDefaultAsync(it => it.RateType == LifePayRateTypeEnum.供应商折扣价);
            CheckExtensions.IfTrueThrowUserFriendlyException(rate != null && input.ChannlesRate < rate.Rate, "渠道折扣无法低于供应商折扣");
            dto.ChannlesName = input.ChannlesName;
            dto.ChannlesNum = input.ChannlesNum;
            dto.ChannlesRate = input.ChannlesRate;
            dto.ChannlesRakeRate = input.ChannlesRakeRate;
            dto.SwitchType = input.SwitchType;
            dto.ChannlesType = input.ChannlesType;
            dto.Status = input.Status;
            dto.AgentType = input.AgentType;
            dto.AreaProvinceId = input.AreaProvinceId;
            dto.AreaCityId = input.AreaCityId;
            #region 记录日志
            await LifePayOrderHistory("渠道管理", "编辑", input.Id.Value, TableType.LifePayChannles);
@@ -1732,6 +1941,13 @@
            CheckExtensions.IfTrueThrowUserFriendlyException(input.ChannlesRate < 0.01m, "渠道折扣设置错误");
            input.Id = Guid.NewGuid();
            var entity = ObjectMapper.Map<CreateEditPayChannelsInput, LifePayChannles>(input);
            if (!string.IsNullOrWhiteSpace(input.PromoterIdNumber) || !string.IsNullOrWhiteSpace(input.PromoterName))
            {
                var promoter = await lifePayPromoterRepository.FirstOrDefaultAsync(it => it.IdNumber == input.PromoterIdNumber && it.Name == input.PromoterName);
                CheckExtensions.IfTrueThrowUserFriendlyException(promoter == null, "该推广人不存在");
                entity.PromoterId = promoter.Id;
            }
            await _lifePayChannlesRep.InsertAsync(entity);
            #region 记录日志
@@ -2124,6 +2340,7 @@
                          PlatformDeductionAmount = a.PlatformDeductionAmount,
                          ACOOLYStatus = a.ACOOLYStatus,
                          LifePayRefundStatus = a.LifePayRefundStatus,
                          OrderParamDetailJsonStr = a.OrderParamDetailJsonStr
                      });
@@ -2144,7 +2361,7 @@
                                         .WhereIf(input.ACOOLYStatus.HasValue, x => x.ACOOLYStatus == input.ACOOLYStatus.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))
                                         .WhereIf(input.KeyWords.IsNotNullOrEmpty(), x => x.PhoneNumber.Contains(input.KeyWords) || x.RefundOrderNo.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.ChannlesNum into temp
                      from b in temp.DefaultIfEmpty()
                      select new LifePayOrderListOutput
@@ -2181,20 +2398,28 @@
                      });
        return result;
    }
    private IQueryable<CreateEditPayChannelsInput> GetLifePayChannlesListFilter()
    {
        return _lifePayChannlesRep.Select(x =>
                    new CreateEditPayChannelsInput
                    {
                        Id = x.Id,
                        ChannlesRate = x.ChannlesRate,
                        ChannlesRakeRate = x.ChannlesRakeRate,
                        ChannlesName = x.ChannlesName,
                        ChannlesNum = x.ChannlesNum,
                        Status = x.Status,
                        SwitchType = x.SwitchType,
                        ChannlesType = x.ChannlesType,
                    });
        return from x in _lifePayChannlesRep
               join p in lifePayPromoterRepository on x.PromoterId equals p.Id into pg
               from pgd in pg.DefaultIfEmpty()
               select new CreateEditPayChannelsInput
               {
                   Id = x.Id,
                   ChannlesRate = x.ChannlesRate,
                   ChannlesRakeRate = x.ChannlesRakeRate,
                   ChannlesName = x.ChannlesName,
                   ChannlesNum = x.ChannlesNum,
                   Status = x.Status,
                   SwitchType = x.SwitchType,
                   ChannlesType = x.ChannlesType,
                   AgentType = x.AgentType,
                   AreaProvinceId = x.AreaProvinceId,
                   AreaCityId = x.AreaCityId,
                   PromoterIdNumber = pgd.IdNumber,
                   PromoterName = pgd.Name,
               };
    }
    public async Task<OrderPriceReturn> GetOrderPrice(decimal price, decimal priceAmount, decimal platformRate, decimal channleRate,