| | |
| | | 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; |
| | | |
| | |
| | | private readonly IRepository<LifePayRate, Guid> _lifePayRateRepository; |
| | | private readonly IRepository<LifePayOrder, Guid> _lifePayOrderRepository; |
| | | private readonly IRepository<LifePayUser, Guid> _lifePayUserRepository; |
| | | private readonly IRepository<LifePayChannles, Guid> _lifePayChannlesRep; |
| | | private readonly IRepository<LifePayAccount, Guid> _lifePayAccount; |
| | | private readonly IDataFilter dataFilter; |
| | | |
| | | private readonly IAliPayApi _aliPayApi; |
| | | private readonly IWxPayApi _wxPayApi; |
| | |
| | | IRepository<LifePayUser, Guid> lifePayUserRepository, |
| | | IAliPayApi aliPayApi, |
| | | IWxPayApi wxPayApi, |
| | | IOptions<WxPayOption> wxPayOptions) |
| | | IOptions<WxPayOption> wxPayOptions, |
| | | IRepository<LifePayChannles, Guid> lifePayChannlesRep, |
| | | IRepository<LifePayAccount, Guid> lifePayAccount, |
| | | IDataFilter dataFilter) |
| | | { |
| | | _logger = logger; |
| | | _aCOOLYManager = aCOOLYManager; |
| | |
| | | _wxPayApi = wxPayApi; |
| | | _wxPayOptions = wxPayOptions.Value; |
| | | _distributedEventBus = distributedEventBus; |
| | | _lifePayChannlesRep = lifePayChannlesRep; |
| | | _lifePayAccount = lifePayAccount; |
| | | this.dataFilter = dataFilter; |
| | | } |
| | | |
| | | #region 查询 |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取话费面值 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<GasParValueResponse> GetGasParValue() |
| | | { |
| | | return await _aCOOLYManager.GasParValue(new GasParValueRequestInput()); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取燃气支持商户 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public async Task<GasOrgTypeValueResponse> GetGasOrgType() |
| | | { |
| | | return await _aCOOLYManager.GasOrgType(new GasOrgTypeRequestInput()); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取折扣 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public async Task<List<LifePayRateListOutput>> GetRate() |
| | | { |
| | | return await _lifePayRateRepository.Select(x => new LifePayRateListOutput() { Rate = x.Rate, RateType = x.RateType }) |
| | | return await _lifePayRateRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayRateListOutput() { Id = x.Id, Rate = x.Rate, RateType = x.RateType }) |
| | | .ToListAsync(); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取用户户号分页数据 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<PageOutput<UserAccountOutput>> GetAccountPage(QueryUserAccountListInput input) |
| | | { |
| | | using (dataFilter.Disable<ISoftDelete>()) |
| | | { |
| | | 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); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取订单分页数据 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<PageOutput<LifePayOrderListOutput>> GetLifePayOrderPage(QueryLifePayOrderListInput input) |
| | | { |
| | | return await _lifePayOrderRepository.Where(x => x.PayStatus != LifePayStatusEnum.未支付) |
| | | .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) |
| | | 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) |
| | | .Select(x => |
| | | new LifePayOrderListOutput |
| | | { |
| | | DiscountAmount = x.DiscountAmount, |
| | | FinishTime = x.FinishTime, |
| | | Id = x.Id, |
| | | LifePayOrderStatus = x.LifePayOrderStatus, |
| | | LifePayOrderType = x.LifePayOrderType, |
| | | LifePayType = x.LifePayType, |
| | | OrderNo = x.OrderNo, |
| | | PayAmount = x.PayAmount, |
| | | PhoneNumber = x.PhoneNumber, |
| | | RechargeAmount = x.RechargeAmount, |
| | | UserId = x.UserId, |
| | | OutOrderNo = x.OutOrderNo, |
| | | PayStatus = x.PayStatus, |
| | | PayTime = x.PayTime, |
| | | RefundCredentialsImgUrl = x.RefundCredentialsImgUrl, |
| | | CreationTime = x.CreationTime |
| | | }) |
| | | .GetPageResult(input.PageModel); |
| | | .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; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | PayStatus = x.PayStatus, |
| | | PayTime = x.PayTime, |
| | | OrderParamDetailJsonStr = x.OrderParamDetailJsonStr, |
| | | RefundCredentialsImgUrl = x.RefundCredentialsImgUrl.GetOssPath(), |
| | | CreationTime = x.CreationTime, |
| | | RefundTime = x.RefundTime |
| | | RefundCheckRemark = x.RefundCheckRemark, |
| | | RefundApplyRemark = x.RefundApplyRemark, |
| | | RefundTime = x.RefundTime, |
| | | ACOOLYOrderNo = x.ACOOLYOrderNo, |
| | | }) |
| | | .GetPageResult(input.PageModel); |
| | | } |
| | | |
| | | public async Task<UserLifePayOrderOutput> 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; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | .FirstOrDefaultAsync(); |
| | | } |
| | | |
| | | public async Task<PageOutput<CreateEditPayChannelsInput>> GetLifePayChannlesPage(PageInput input) |
| | | { |
| | | return await GetLifePayChannlesListFilter().GetPageResult(input.PageModel); |
| | | } |
| | | |
| | | public async Task<List<CreateEditPayChannelsInput>> GetLifePayChannlesAllList() |
| | | { |
| | | return await GetLifePayChannlesListFilter().Where(x => x.Status == LifePayChannelsStatsEnum.启用).ToListAsync(); |
| | | } |
| | | |
| | | public async Task<CreateEditPayChannelsInput> 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<CreateEditPayChannelsInput> 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<UserLifePayOrderRefundOutput> 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<PageOutput<UserAccountOutput>> GetUserAccountList(QueryUserAccountListInput input) |
| | | { |
| | | if (!input.UserId.HasValue) |
| | | { |
| | | return new PageOutput<UserAccountOutput>(); |
| | | } |
| | | |
| | | 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<List<UserAccountOutput>> GetUserAccountAllList(QueryUserAccountAllListInput input) |
| | | { |
| | | if (!input.UserId.HasValue) |
| | | { |
| | | return new List<UserAccountOutput>(); |
| | | } |
| | | |
| | | 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<UserAccountOutput> 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<List<LifePayOrderListTemplate>> 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 操作 |
| | |
| | | /// <returns></returns> |
| | | public async Task<CreateLifePayOrderOutput> CreateLifePayPhoneOrder(CreateLifePayOrderInput<LifePhoneData> 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(), "未配置折扣"); |
| | |
| | | PayAmount = amount.PayAmont, |
| | | DiscountAmount = amount.DiscountAmount, |
| | | RechargeAmount = amount.RechargeAmount, |
| | | ChannelId = channle.Id |
| | | }; |
| | | |
| | | await CreateLifePayOrder(orderInput); |
| | |
| | | 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(), "未配置折扣"); |
| | | |
| | |
| | | PayAmount = amount.PayAmont, |
| | | DiscountAmount = amount.DiscountAmount, |
| | | RechargeAmount = amount.RechargeAmount, |
| | | ChannelId = channle.Id |
| | | }; |
| | | |
| | | await CreateLifePayOrder(orderInput); |
| | | |
| | | var result = new CreateLifePayOrderOutput() |
| | | { |
| | | OrderNo = orderInput.OrderNo, |
| | | }; |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建生活缴费燃气订单 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<CreateLifePayOrderOutput> CreateLifePayGasOrder(CreateLifePayOrderInput<LifeGasData> 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); |
| | |
| | | case LifePayOrderTypeEnum.电费订单: |
| | | desc += "电费"; |
| | | break; |
| | | case LifePayOrderTypeEnum.燃气订单: |
| | | desc += "燃气"; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | |
| | | |
| | | // var result = await PayTransactionsJsAPI(input.OpenId, input.Attach, order.PayAmount, input.OrderNo, desc); |
| | | |
| | | 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); |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | |
| | | return (result.Code, requestInput.RequestNo, result.ElectricChargeOrder.BusiOrderNo); |
| | | } |
| | | |
| | | public async Task<ModelPaymentMiniPay> PayTransactionsJsAPI(string openid, string order_guid, decimal amount, string outTradeNo, string description) |
| | | /// <summary> |
| | | /// 创建ACOOLY燃气订单 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYGasOrder(LifeGasData input, string orderNo) |
| | | { |
| | | string time_expire = DateTime.Now.AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00";//订单失效时间 |
| | | 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<ModelPaymentMiniPay> 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 = _wxPayOptions.AppID, |
| | | Appid = appId, |
| | | Mchid = _wxPayOptions.Mchid, |
| | | Attach = order_guid, |
| | | Description = description, |
| | |
| | | if (res != null) |
| | | { |
| | | |
| | | string paytext = BuildSignByPay(_wxPayOptions.AppID, timestamp, nonce, package); |
| | | string paytext = BuildSignByPay(appId, timestamp, nonce, package); |
| | | string paysign = _wxPayApi.GeneratePaySignByKey(paytext); |
| | | |
| | | info.Timestamp = timestamp.ToString(); |
| | |
| | | break; |
| | | case LifePayOrderTypeEnum.电费订单: |
| | | result = await CreateACOOLYElectricOrder(JsonConvert.DeserializeObject<LifeElectricData>(order.OrderParamDetailJsonStr), order.OrderNo); |
| | | break; |
| | | case LifePayOrderTypeEnum.燃气订单: |
| | | result = await CreateACOOLYGasOrder(JsonConvert.DeserializeObject<LifeGasData>(order.OrderParamDetailJsonStr), order.OrderNo); |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | return; |
| | | } |
| | | |
| | | if (order.LifePayOrderStatus != LifePayOrderStatusEnum.已失败 && order.PayStatus != LifePayStatusEnum.待退款) |
| | | 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); |
| | | |
| | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 用户发起生活缴费退款 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="UserFriendlyException"></exception> |
| | | 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<WxPayDomesticRefundsReponse> 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<int> 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; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 用户删除户号信息 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<int> 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; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 退款驳回 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="UserFriendlyException"></exception> |
| | | 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<CreateEditPayChannelsInput, LifePayChannles>(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<bool> 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<LifePayRateInput> input) |
| | | { |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate <= 0).Any(), "折扣不得小于等于0"); |
| | | var baseRate = input.FirstOrDefault(r => r.RateType == LifePayRateTypeEnum.供应商折扣价)?.Rate; |
| | | var listData = new List<LifePayRate>(); |
| | | 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 私有 |
| | |
| | | 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, 2, MidpointRounding.AwayFromZero); |
| | | /// 正常支付 |
| | | 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); |
| | |
| | | { |
| | | var codeUrl = string.Empty; |
| | | switch (payType) |
| | | |
| | | |
| | | |
| | | { |
| | | case LifePayTypeEnum.AliPay: |
| | | codeUrl = await GetAliPayQRCode(outTradeNo, description, amount); |
| | |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | } |
| | | private async Task<IQueryable<LifePayOrderListOutput>> 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<CreateEditPayChannelsInput> 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 |
| | | } |