using System; using System.Threading.Tasks; using AIK.Models.ApiModels.Payment; using AIK.Service.IService; using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.Extensions.Logging; using System.Diagnostics; using System.Windows.Threading; namespace AIK.ViewModels.Integral { public partial class PaymentQrCodeViewModel : ObservableObject { private readonly IPaymentOrderService _paymentOrderService; private readonly IUserSessionCoordinator _userSessionCoordinator; private readonly ILogger _logger; private readonly DispatcherTimer _timer; public PaymentQrCodeViewModel( IPaymentOrderService paymentOrderService, IUserSessionCoordinator userSessionCoordinator, ILogger logger) { _paymentOrderService = paymentOrderService; _userSessionCoordinator = userSessionCoordinator; _logger = logger; _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2) }; _timer.Tick += OnTimerTick; } [ObservableProperty] private long _orderId; [ObservableProperty] private decimal _amount; [ObservableProperty] private byte[]? _qrCodeBytes; [ObservableProperty] private string _statusMessage = #if CN || TEST "请使用微信扫码支付"; #else "请在浏览器中完成PayPal支付"; #endif [ObservableProperty] private bool _isPaid; [ObservableProperty] private bool _isQrCodeMode = #if CN || TEST true; #else false; #endif [ObservableProperty] private string _paymentButtonText = #if CN || TEST "关闭"; #else "重新打开PayPal"; #endif [ObservableProperty] private string _paymentLaunchUrl = string.Empty; public event Action? PaymentSucceeded; public void Start(PaymentParametersPC payment, decimal amount, byte[] qrCodeBytes) { OrderId = payment.id; Amount = amount; QrCodeBytes = qrCodeBytes; #if CN || TEST StatusMessage = "请使用微信扫码支付"; #else PaymentLaunchUrl = PaymentLaunchHelper.BuildPaypalLaunchUrl(payment.PaypalApproveUrl ?? string.Empty); StatusMessage = "请在浏览器中完成PayPal支付"; TryOpenPaypal(); #endif IsPaid = false; _timer.Start(); } public void Stop() { _timer.Stop(); } private async void OnTimerTick(object? sender, EventArgs e) { if (OrderId <= 0) { return; } try { #if CN || TEST var status = await _paymentOrderService.GetOrderPayStatusAsync(OrderId, 2); #else int? status = null; try { status = await _paymentOrderService.RefreshPaypalOrderAsync(OrderId, 2); } catch (Exception ex) { _logger.LogWarning(ex, "刷新PayPal订单状态失败,继续查询订单支付状态,订单:{OrderId}", OrderId); } status ??= await _paymentOrderService.GetOrderPayStatusAsync(OrderId, 2); #endif switch (status) { case 1: _timer.Stop(); IsPaid = true; StatusMessage = "支付成功,正在刷新积分..."; await _userSessionCoordinator.RefreshIntegralAsync(); PaymentSucceeded?.Invoke(); break; case -1: _timer.Stop(); StatusMessage = "支付失败,请重新发起支付"; break; case 2: _timer.Stop(); StatusMessage = "支付已取消"; break; default: #if CN || TEST StatusMessage = "等待支付完成..."; #else StatusMessage = "等待PayPal支付完成..."; #endif break; } } catch (Exception ex) { _logger.LogWarning(ex, "查询积分充值支付状态失败,订单:{OrderId}", OrderId); #if CN || TEST StatusMessage = "正在等待支付结果..."; #else StatusMessage = "正在等待PayPal支付结果..."; #endif } } public void ReopenPaypal() { #if !(CN || TEST) TryOpenPaypal(); #endif } #if !(CN || TEST) private void TryOpenPaypal() { if (string.IsNullOrWhiteSpace(PaymentLaunchUrl)) { StatusMessage = "PayPal支付链接无效"; return; } try { Process.Start(new ProcessStartInfo { FileName = PaymentLaunchUrl, UseShellExecute = true }); } catch (Exception ex) { _logger.LogWarning(ex, "打开PayPal支付页面失败,订单:{OrderId}", OrderId); StatusMessage = "无法自动打开PayPal页面,请稍后重试"; } } #endif } }