兼容win7版应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.5 KiB

using System;
using System.Threading.Tasks;
using AIK.Common.Interface;
using AIK.Common.Language;
using AIK.Models.ApiModels.Payment;
using AIK.Service.IService;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
namespace AIK.ViewModels.Integral
{
public partial class IntegralRechargeViewModel : ObservableObject
{
private const decimal MinRechargeAmount = 0.01m;
private const int IntegralRate = 50;
private readonly IDataCacheService _dataCacheService;
private readonly IPaymentOrderService _paymentOrderService;
private readonly IQRCodeService _qrCodeService;
private readonly IUserSessionCoordinator _userSessionCoordinator;
private readonly ILogger<IntegralRechargeViewModel> _logger;
public IntegralRechargeViewModel(
IDataCacheService dataCacheService,
IPaymentOrderService paymentOrderService,
IQRCodeService qrCodeService,
IUserSessionCoordinator userSessionCoordinator,
ILogger<IntegralRechargeViewModel> logger)
{
_dataCacheService = dataCacheService;
_paymentOrderService = paymentOrderService;
_qrCodeService = qrCodeService;
_userSessionCoordinator = userSessionCoordinator;
_logger = logger;
AmountOptions = new ObservableCollection<RechargeAmountOption>
{
new(50, 2500),
new(100, 5000),
new(200, 10000),
new(300, 15000),
new(400, 20000),
new(500, 25000)
};
}
public ObservableCollection<RechargeAmountOption> AmountOptions { get; }
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(PayCommand))]
private decimal? _amount;
[ObservableProperty]
private int _currentIntegral;
[ObservableProperty]
private int _expectedIntegral;
[ObservableProperty]
private string _statusMessage = string.Empty;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(PayCommand))]
private bool _isBusy;
public event Action<PaymentParametersPC, decimal, byte[]?>? PaymentCreated;
partial void OnAmountChanged(decimal? value)
{
ExpectedIntegral = value.HasValue ? (int)(value.Value * IntegralRate) : 0;
foreach (var option in AmountOptions)
{
option.IsSelected = value.HasValue && option.Amount == value.Value;
}
}
[RelayCommand]
private void SelectAmount(RechargeAmountOption option)
{
Amount = option.Amount;
}
[RelayCommand(CanExecute = nameof(CanPay))]
private async Task PayAsync()
{
if (!Amount.HasValue || Amount.Value < MinRechargeAmount)
{
StatusMessage = GetLanguageText("RechargeMinAmountInvalid");
return;
}
var token = await _dataCacheService.GetLatestUserTokenAsync();
if (string.IsNullOrWhiteSpace(token))
{
StatusMessage = GetLanguageText("RechargeLoginRequired");
return;
}
IsBusy = true;
StatusMessage = GetLanguageText("RechargeCreatingOrder");
try
{
var payment = await _paymentOrderService.CreateIntegralOrderAsync(token, new CreateIntegralOrderRequest
{
Amount = Amount.Value,
#if CN || TEST
PayType = 2
#else
PayType = 5
#endif
});
#if CN || TEST
if (payment == null || string.IsNullOrWhiteSpace(payment.code_url))
{
StatusMessage = GetLanguageText("RechargePcQrCodeMissing");
return;
}
var qrBytes = _qrCodeService.GenerateQRCodeWithLogo(payment.code_url, GetLogoPath(), 10);
StatusMessage = GetLanguageText("RechargeWechatScanToPay");
PaymentCreated?.Invoke(payment, Amount.Value, qrBytes);
#else
if (payment == null || string.IsNullOrWhiteSpace(payment.PaypalApproveUrl))
{
StatusMessage = GetLanguageText("RechargePaypalParametersMissing");
return;
}
StatusMessage = GetLanguageText("RechargeOpeningPaypal");
PaymentCreated?.Invoke(payment, Amount.Value, null);
#endif
}
catch (Exception ex)
{
_logger.LogError(ex, "创建积分充值订单失败");
StatusMessage = GetLanguageText("RechargeCreateOrderFailed");
}
finally
{
IsBusy = false;
}
}
public async Task RefreshIntegralAsync()
{
await _userSessionCoordinator.RefreshIntegralAsync();
}
private bool CanPay()
{
return !IsBusy && Amount.HasValue && Amount.Value >= MinRechargeAmount;
}
private static string GetLogoPath()
{
#if CN || TEST
return "AIK.Assets.Images.AIKChina.png";
#else
return "AIK.Assets.Images.AIKInternationl.png";
#endif
}
private static string GetLanguageText(string key)
{
return AiKLanguage.LanguageKey?.GetValueOrDefault(key) ?? string.Empty;
}
}
}