sunpengfei
2025-06-16 e0f2b29f3349d43e7f4222e079c54ba9cc4b6ee1
LifePayment/LifePayment.Application/LifePay/LifePayService.cs
@@ -1,4 +1,5 @@
using LifePayment.Application.Contracts;
using Alipay.EasySDK.Payment.Common.Models;
using LifePayment.Application.Contracts;
using LifePayment.Domain;
using LifePayment.Domain.LifePay;
using LifePayment.Domain.Models;
@@ -7,30 +8,23 @@
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 Alipay.EasySDK.Payment.Common.Models;
using static LifePayment.Domain.Shared.LifePaymentConstant;
using ZeroD.Util.Fadd;
using Nest;
using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectMapping;
using NPOI.SS.Formula.Functions;
using StackExchange.Redis;
using static Volo.Abp.Identity.Settings.IdentitySettingNames;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using LifePayment.Application.LifePay;
using Alipay.AopSdk.Core.Domain;
using static LifePayment.Domain.Shared.LifePaymentConstant;
namespace LifePayment.Application;
@@ -52,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;
@@ -59,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,
@@ -79,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;
@@ -100,11 +99,11 @@
        _lifePayAccount = lifePayAccount;
        this.dataFilter = dataFilter;
        _channelFilter = channelFilter;
        this.distributedLock = distributedLock;
        _operateHistory = operateHistory;
    }
    #region 查询
    /// <summary>
    /// 获取电费面值
@@ -133,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>
@@ -280,16 +289,16 @@
                                DiscountAmount = a.DiscountAmount ?? 0,
                                FinishTime = a.FinishTime,
                                Id = a.Id,
                                LifePayOrderStatus = a.LifePayOrderStatus?? 0,
                                LifePayOrderStatus = a.LifePayOrderStatus ?? 0,
                                LifePayOrderType = a.LifePayOrderType,
                                LifePayType = a.LifePayType,
                                OrderNo = a.OrderNo,
                                PayAmount = a.PayAmount ?? 0,
                                PhoneNumber = a.PhoneNumber,
                                RechargeAmount = a.RechargeAmount??0,
                                RechargeAmount = a.RechargeAmount ?? 0,
                                UserId = a.UserId,
                                OutOrderNo = a.OutOrderNo,
                                PayStatus = a.PayStatus?? 0,
                                PayStatus = a.PayStatus ?? 0,
                                PayTime = a.PayTime,
                                ACOOLYOrderNo = a.ACOOLYOrderNo,
                                RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(),
@@ -300,11 +309,45 @@
                                RefundTime = a.RefundTime,
                                ChannelName = b.ChannlesName,
                                ActualRechargeAmount = a.RechargeAmount,
                                ActualReceivedAmount = a.ActualReceivedAmount,
                                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;
    }
@@ -358,6 +401,7 @@
                                RefundPrice = a.RefundPrice,
                                ChannelName = b.ChannlesName,
                                ActualRechargeAmount = a.RechargeAmount,
                                ActualReceivedAmount = a.ActualReceivedAmount,
                                PlatformDeductionAmount = a.PlatformDeductionAmount,
                                ACOOLYStatus = a.ACOOLYStatus,
                                LifePayRefundStatus = a.LifePayRefundStatus,
@@ -388,7 +432,7 @@
            ACOOLYStatus = x.ACOOLYStatus,
            RefundApplyRemark = x.RefundApplyRemark,
            RechargeAmount = x.RechargeAmount,
            ActualReceivedAmount = x.ActualReceivedAmount.ToString("F2"),
            ActualReceivedAmount = (x.ActualReceivedAmount ?? 0).ToString("F2"),
            LifePayRefundStatus = x.LifePayRefundStatus,
            OrderNo = x.OrderNo,
@@ -407,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;
    }
@@ -458,6 +503,7 @@
            PremiumPrice = orderpirce.PremiumPrice,
            Profit = orderpirce.Profit,
            RefundOrderNo = order.RefundOrderNo,
            ActualReceivedAmount = order.ActualReceivedAmount
        };
        return result;
@@ -567,7 +613,7 @@
                                                        DiscountAmount = x.DiscountAmount ?? 0,
                                                        FinishTime = x.FinishTime,
                                                        Id = x.Id,
                                                        LifePayOrderStatus = x.LifePayOrderStatus?? 0 ,
                                                        LifePayOrderStatus = x.LifePayOrderStatus ?? 0,
                                                        LifePayOrderType = x.LifePayOrderType,
                                                        LifePayType = x.LifePayType,
                                                        OrderNo = x.OrderNo,
@@ -610,7 +656,7 @@
    public async Task<List<CreateEditPayChannelsInput>> GetLifePayChannlesAllList(QueryLifePayChannlesInput input)
    {
        return await GetLifePayChannlesListFilter().WhereIf(input.Status.HasValue,x => x.Status == input.Status).ToListAsync();
        return await GetLifePayChannlesListFilter().WhereIf(input.Status.HasValue, x => x.Status == input.Status).ToListAsync();
    }
    public async Task<CreateEditPayChannelsInput> GetLifePayChannlesDto(Guid id)
@@ -761,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 =>
@@ -779,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
@@ -908,7 +1058,7 @@
        return await _wxPayApi.WxPayTradeQuery(outTradeNo);
    }
    #endregion
@@ -930,18 +1080,17 @@
        var channle = await GetLifePayChannlesDtoByNum(input.ChannelId);
        CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "渠道不存在");
        var repeatOrder = await _lifePayOrderRepository.Where(x => x.LifePayOrderType == LifePayOrderTypeEnum.PhoneOrder
        var repeatOrder = await _lifePayOrderRepository.Where(x => x.LifePayOrderType == LifePayOrderTypeEnum.PhoneOrder
        && x.PayStatus == LifePayStatusEnum.已支付
        && x.LifePayOrderStatus == LifePayOrderStatusEnum.充值中
        && x.OrderParamDetailJsonStr.Contains(input.ProductData.Phone)).AnyAsync();
         CheckExtensions.IfTrueThrowUserFriendlyException(repeatOrder, "您有同户号订单正在充值中,请勿重复充值");
        CheckExtensions.IfTrueThrowUserFriendlyException(repeatOrder, "您有同户号订单正在充值中,请勿重复充值");
        var rate = await GetLifePayRate(channle, LifePayRateTypeEnum.默认话费折扣);
        var amount = CalculateAmount(input.ProductData.ParValue, rate);
        var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价);
        var orderInput = new CreateLifePayOrderInput
        {
@@ -1298,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;
        }
@@ -1326,6 +1476,7 @@
                default:
                    break;
            }
            _logger.LogInformation("已向供应商发起订单");
            order.LifePayRefundStatus = LifePayRefundStatusEnum.无需退款;
            order.LifePayOrderStatus = LifePayOrderStatusEnum.充值中;
@@ -1333,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)
        {
@@ -1346,7 +1499,6 @@
            order.ACOOLYStatus = ACOOLYStatusEnum.充值失败;
            order.RefundApplyRemark = ex.Message;
        }
        _logger.LogError("生活缴费订单状态:" + order.LifePayOrderStatus.ToString());
        await _lifePayOrderRepository.UpdateAsync(order);
    }
@@ -1377,63 +1529,95 @@
    /// <param name="orderNo"></param>
    /// <param name="outOrderNo"></param>
    /// <returns></returns>
    public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status, ACOOLYStatusEnum acoolyStatus, decimal payAmount, string refundApplyRemark)
    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);
            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>
@@ -1514,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);
@@ -1690,14 +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.LifePayRefundStatus = LifePayRefundStatusEnum.待退款;
            }
            order.RefundCheckRemark = input.RefundCheckRemark;
            order.RefundCheckUserId = CurrentUser.Id;
            order.LifePayRefundStatus = LifePayRefundStatusEnum.退款驳回;
            await _lifePayOrderRepository.UpdateAsync(order);
@@ -1719,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);
@@ -1737,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 记录日志
@@ -2129,6 +2340,7 @@
                          PlatformDeductionAmount = a.PlatformDeductionAmount,
                          ACOOLYStatus = a.ACOOLYStatus,
                          LifePayRefundStatus = a.LifePayRefundStatus,
                          OrderParamDetailJsonStr = a.OrderParamDetailJsonStr
                      });
@@ -2149,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
@@ -2186,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,
@@ -2271,12 +2491,12 @@
            default:
                break;
        }
        return new SetPayTypeReturn()
        {
            Desc = desc,
            OrderNo = order.OrderNo,
            PayAmount = order.PayAmount.HasValue? order.PayAmount.Value : 0,
            PayAmount = order.PayAmount.HasValue ? order.PayAmount.Value : 0,
            LifePayType = lifePayType,
        };
    }