sunpengfei
2025-06-10 c16fb1bb2431f40eb4b8e1af13c5254e2cf41d5a
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,8 +8,10 @@
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;
@@ -19,18 +22,7 @@
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;
namespace LifePayment.Application;
@@ -59,10 +51,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,
@@ -83,6 +77,7 @@
    {
        _logger = logger;
        _aCOOLYManager = aCOOLYManager;
        this.lifePayPromoterRepository = lifePayPromoterRepository;
        _lifePayRateRepository = lifePayRateRepository;
        _lifePayOrderRepository = lifePayOrderRepository;
        _lifePayUserRepository = lifePayUserRepository;
@@ -104,7 +99,6 @@
    }
    #region 查询
    /// <summary>
    /// 获取电费面值
@@ -133,6 +127,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>
@@ -305,7 +309,6 @@
                                ACOOLYStatus = a.ACOOLYStatus,
                                LifePayRefundStatus = a.LifePayRefundStatus,
                            }).GetPageResult(input.PageModel);
        return result;
    }
@@ -359,6 +362,7 @@
                                RefundPrice = a.RefundPrice,
                                ChannelName = b.ChannlesName,
                                ActualRechargeAmount = a.RechargeAmount,
                                ActualReceivedAmount = a.ActualReceivedAmount,
                                PlatformDeductionAmount = a.PlatformDeductionAmount,
                                ACOOLYStatus = a.ACOOLYStatus,
                                LifePayRefundStatus = a.LifePayRefundStatus,
@@ -408,6 +412,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;
    }
@@ -459,6 +464,7 @@
            PremiumPrice = orderpirce.PremiumPrice,
            Profit = orderpirce.Profit,
            RefundOrderNo = order.RefundOrderNo,
            ActualReceivedAmount = order.ActualReceivedAmount
        };
        return result;
@@ -781,8 +787,56 @@
            s.LifePayOrderStatusStr = s.LifePayOrderStatus.GetDescription();
            s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmmss);
        });
        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
        }).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);
        });
        CheckExtensions.IfTrueThrowUserFriendlyException(result.IsNullOrEmpty(), "暂无数据导出");
        return result;
    }
    public async Task<string> GetBillErceiptExport(string orderNo)
    {
        try
@@ -942,7 +996,6 @@
        var amount = CalculateAmount(input.ProductData.ParValue, rate);
        var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价);
        var orderInput = new CreateLifePayOrderInput
        {
@@ -1299,9 +1352,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;
        }
@@ -1327,6 +1381,7 @@
                default:
                    break;
            }
            _logger.LogInformation("已向供应商发起订单");
            order.LifePayRefundStatus = LifePayRefundStatusEnum.无需退款;
            order.LifePayOrderStatus = LifePayOrderStatusEnum.充值中;
@@ -1334,10 +1389,13 @@
            order.OutRequestNo = result.RequestNo.IsNullOrEmpty() ? null : result.RequestNo;
            order.ACOOLYOrderNo = result.ACOOLYOrderNo;
            order.ACOOLYStatus = ACOOLYStatusEnum.充值中;
            await _lifePayOrderRepository.UpdateAsync(order);
            _logger.LogInformation("生活缴费订单状态:" + order.LifePayOrderStatus.ToString());
            /// 创建生活缴费消费记录
            await _lifePayOrderService.CreatLifePayConsumption(ACOOLYStatusEnum.充值中, order.OrderNo, order.ACOOLYOrderNo,
                                order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime);
            _logger.LogInformation("已插入消费记录");
        }
        catch (Exception ex)
        {
@@ -1346,10 +1404,9 @@
            order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款;
            order.ACOOLYStatus = ACOOLYStatusEnum.充值失败;
            order.RefundApplyRemark = ex.Message;
            await _lifePayOrderRepository.UpdateAsync(order);
            _logger.LogError("生活缴费订单状态:" + order.LifePayOrderStatus.ToString());
        }
        _logger.LogError("生活缴费订单状态:" + order.LifePayOrderStatus.ToString());
        await _lifePayOrderRepository.UpdateAsync(order);
    }
    public async Task LifePayRefundsHandler(string orderNo, LifePayRefundStatusEnum refundStatus)
@@ -1378,17 +1435,19 @@
    /// <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.已完成)
        if (order.LifePayOrderStatus == status && order.ACOOLYStatus == acoolyStatus)
        {
            _logger.LogInformation($"订单({orderNo})已处理该状态");
            return;
        }
        // order.PlatformDeductionAmount = payAmount;
        order.ActualReceivedAmount = actualParValue;
        order.PlatformDeductionAmount = Math.Round((order.ActualReceivedAmount ?? 0) * (order.PlatformRate ?? 0) / 100, 2);
        if (acoolyOrderNo.IsNotNullOrEmpty())
        {
@@ -1407,7 +1466,18 @@
        order.LifePayOrderStatus = status;
        order.ACOOLYStatus = acoolyStatus;
        order.FinishTime = DateTime.Now;
        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);
        }
        await _lifePayOrderRepository.UpdateAsync(order);
        if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成)
@@ -1434,7 +1504,7 @@
        /// 创建生活缴费消费记录
        await _lifePayOrderService.CreatLifePayConsumption(acoolyStatus, order.OrderNo, order.ACOOLYOrderNo,
                    order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime);
                    order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime, order.ChannleRate, parValue, actualParValue);
    }
    /// <summary>
@@ -1515,6 +1585,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);
@@ -1695,6 +1767,10 @@
            {
                order.LifePayOrderStatus = LifePayOrderStatusEnum.已完成;
            }
            else
            {
                order.LifePayOrderStatus = LifePayOrderStatusEnum.退款失败;
            }
            order.RefundCheckRemark = input.RefundCheckRemark;
            order.RefundCheckUserId = CurrentUser.Id;
@@ -1720,13 +1796,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);
@@ -1738,6 +1827,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 记录日志
@@ -2187,20 +2283,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,