Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 28695a88f8 | |||
| a2e1e1fead |
@@ -11,8 +11,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
|
||||
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf -->
|
||||
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.181" />
|
||||
<!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />-->
|
||||
<!-- <PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.181" />-->
|
||||
<ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />
|
||||
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
|
||||
@@ -37,7 +37,7 @@ else
|
||||
<MudGrid Spacing="4" Justify="Justify.Center">
|
||||
@foreach (var license in _licenseImages)
|
||||
{
|
||||
<MudItem xs="12" sm="6" md="4">
|
||||
<MudItem xs="6" sm="6" md="4">
|
||||
<MudCard Elevation="2" Class="h-100">
|
||||
<MudCardMedia Image="@license.ImagePath" Height="250" />
|
||||
<MudCardContent>
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
@attribute [Route(RouteConstants.Profile.ChargeDiscountWallet)]
|
||||
@attribute [Authorize]
|
||||
|
||||
<PageTitle>شارژ کیفپول اعتباری</PageTitle>
|
||||
|
||||
<MudContainer MaxWidth="MaxWidth.Medium" Class="py-6">
|
||||
<MudStack Spacing="3">
|
||||
<PageHeader Title="💳 شارژ کیفپول اعتباری" BackHref="@RouteConstants.Profile.Wallet" />
|
||||
|
||||
@* ─── نتیجه پرداخت (اگه از callback برگشته) ─── *@
|
||||
@if (_paymentResult != null)
|
||||
{
|
||||
<MudAlert Severity="@(_paymentResult == "success" ? MudBlazor.Severity.Success : MudBlazor.Severity.Error)"
|
||||
Class="rounded-lg" Variant="Variant.Filled">
|
||||
@if (_paymentResult == "success")
|
||||
{
|
||||
<span>شارژ اعتباری با موفقیت انجام شد! ✅</span>
|
||||
}
|
||||
else if (_paymentResult == "cancelled")
|
||||
{
|
||||
<span>پرداخت توسط شما لغو شد.</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>پرداخت ناموفق بود. لطفاً دوباره تلاش کنید.</span>
|
||||
}
|
||||
</MudAlert>
|
||||
}
|
||||
|
||||
@* ─── فرم شارژ ─── *@
|
||||
<MudPaper Elevation="2" Class="pa-5 rounded-lg">
|
||||
<MudText Typo="Typo.h6" Class="mb-3">
|
||||
<MudIcon Icon="@Icons.Material.Filled.CreditCard" Class="ml-1" />
|
||||
شارژ موجودی اعتباری
|
||||
</MudText>
|
||||
|
||||
<MudAlert Severity="MudBlazor.Severity.Info" Dense="true" Class="mb-3" Icon="@Icons.Material.Filled.Info">
|
||||
مبلغ وارد شده (به تومان) از طریق درگاه پرداخت به موجودی اعتباری شما اضافه میشود.
|
||||
از موجودی اعتباری فقط برای خرید از فروشگاه تخفیفی میتوانید استفاده کنید.
|
||||
</MudAlert>
|
||||
|
||||
<MudStack Spacing="2">
|
||||
<MudNumericField @bind-Value="_chargeAmount"
|
||||
Label="مبلغ (تومان)"
|
||||
Variant="Variant.Outlined"
|
||||
Min="10_000"
|
||||
Max="100_000_000"
|
||||
Format="N0"
|
||||
Adornment="Adornment.Start"
|
||||
AdornmentIcon="@Icons.Material.Filled.Payments"
|
||||
HelperText="حداقل ۱۰,۰۰۰ و حداکثر ۱۰۰,۰۰۰,۰۰۰ تومان" />
|
||||
|
||||
@* دکمههای مبلغ سریع *@
|
||||
<MudStack Row="true" Spacing="1" Class="flex-wrap">
|
||||
@foreach (var preset in _presetAmounts)
|
||||
{
|
||||
<MudButton Variant="Variant.Outlined" Size="Size.Small"
|
||||
Color="@(_chargeAmount == preset ? Color.Primary : Color.Default)"
|
||||
OnClick="() => _chargeAmount = preset"
|
||||
Class="rounded-pill">
|
||||
@FormatToman(preset)
|
||||
</MudButton>
|
||||
}
|
||||
</MudStack>
|
||||
|
||||
@if (_chargeAmount > 0)
|
||||
{
|
||||
<MudPaper Outlined="true" Class="pa-3 rounded-lg" Style="background: #f0fdf4;">
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
||||
<MudText Typo="Typo.body2">مبلغ پرداخت:</MudText>
|
||||
<MudText Typo="Typo.body2"><strong>@FormatToman(_chargeAmount)</strong></MudText>
|
||||
</MudStack>
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
||||
<MudText Typo="Typo.body2">اعتبار دریافتی:</MudText>
|
||||
<MudText Typo="Typo.body2" Color="Color.Success"><strong>@FormatToman(_chargeAmount)</strong></MudText>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
}
|
||||
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Primary"
|
||||
Size="Size.Large"
|
||||
FullWidth="true"
|
||||
Disabled="@(_chargeAmount <= 0 || _isProcessing)"
|
||||
OnClick="StartDiscountCharge"
|
||||
StartIcon="@Icons.Material.Filled.Payment"
|
||||
Class="rounded-lg mt-2">
|
||||
@if (_isProcessing)
|
||||
{
|
||||
<MudProgressCircular Indeterminate="true" Size="Size.Small" Class="ml-2" />
|
||||
<span>در حال انتقال به درگاه...</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>پرداخت از درگاه</span>
|
||||
}
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
|
||||
@* ─── قوانین ─── *@
|
||||
<MudExpansionPanels Elevation="1" Class="rounded-lg">
|
||||
<MudExpansionPanel Text="قوانین شارژ اعتباری" MaxHeight="500" IsInitiallyExpanded="false">
|
||||
<MudList T="string" Dense="true">
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.CheckCircle" IconColor="Color.Success">
|
||||
موجودی اعتباری فقط قابل استفاده در فروشگاه تخفیفی است
|
||||
</MudListItem>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.CheckCircle" IconColor="Color.Success">
|
||||
حداقل مبلغ شارژ: ۱۰,۰۰۰ تومان
|
||||
</MudListItem>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.CheckCircle" IconColor="Color.Success">
|
||||
مبلغ واریزی بدون ضریب به موجودی اضافه میشود (۱:۱)
|
||||
</MudListItem>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Info" IconColor="Color.Info">
|
||||
پرداخت از طریق درگاه بانکی انجام میشود
|
||||
</MudListItem>
|
||||
</MudList>
|
||||
</MudExpansionPanel>
|
||||
</MudExpansionPanels>
|
||||
</MudStack>
|
||||
</MudContainer>
|
||||
@@ -0,0 +1,59 @@
|
||||
using FrontOffice.Main.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
|
||||
namespace FrontOffice.Main.Pages.Profile;
|
||||
|
||||
public partial class ChargeDiscountWallet : ComponentBase
|
||||
{
|
||||
private bool _isProcessing;
|
||||
private long _chargeAmount;
|
||||
private string? _paymentResult;
|
||||
|
||||
private readonly long[] _presetAmounts = { 500_000, 1_000_000, 5_000_000, 10_000_000, 20_000_000, 50_000_000 };
|
||||
|
||||
[SupplyParameterFromQuery(Name = "payment")]
|
||||
public string? PaymentQueryParam { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_paymentResult = PaymentQueryParam;
|
||||
}
|
||||
|
||||
private async Task StartDiscountCharge()
|
||||
{
|
||||
if (_chargeAmount <= 0 || _isProcessing) return;
|
||||
|
||||
_isProcessing = true;
|
||||
StateHasChanged();
|
||||
|
||||
try
|
||||
{
|
||||
// تبدیل تومان به ریال
|
||||
var amountInRial = _chargeAmount * 10;
|
||||
|
||||
var (success, gatewayUrl, error) = await WalletService.InitiateDiscountChargeAsync(amountInRial);
|
||||
|
||||
if (success && !string.IsNullOrEmpty(gatewayUrl))
|
||||
{
|
||||
Navigation.NavigateTo(gatewayUrl, forceLoad: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Snackbar.Add(error ?? "خطا در ایجاد درخواست پرداخت", Severity.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"خطا: {ex.Message}", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isProcessing = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatToman(long toman)
|
||||
=> string.Format("{0:N0} تومان", toman);
|
||||
}
|
||||
@@ -214,13 +214,25 @@
|
||||
<MudText Typo="Typo.subtitle1" Color="Color.Primary"><b>پرداخت مستقیم</b></MudText>
|
||||
</MudStack>
|
||||
<MudText Typo="Typo.body2" Class="mud-text-secondary">پرداخت آنی از طریق درگاه بانکی</MudText>
|
||||
@if (_purchaseCycleCount > 0)
|
||||
{
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" FullWidth="true"
|
||||
StartIcon="@Icons.Material.Filled.Payment" OnClick="DirectPayment">
|
||||
پرداخت با کارت بانکی
|
||||
</MudButton>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudButton Variant="Variant.Filled" Disabled="true" Color="Color.Primary" FullWidth="true"
|
||||
StartIcon="@Icons.Material.Filled.Payment" OnClick="DirectPayment">
|
||||
پرداخت با کارت بانکی(بزودی)
|
||||
</MudButton>
|
||||
}
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
|
||||
@if (_purchaseCycleCount == 0)
|
||||
{
|
||||
<MudPaper Elevation="0" Class="pa-4 rounded-lg" Style="border: 2px solid var(--mud-palette-tertiary);">
|
||||
<MudStack Spacing="2">
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
||||
@@ -234,6 +246,13 @@
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudAlert Severity="Severity.Info" Dense="true" Class="mt-1">
|
||||
از دور دوم به بعد، خرید پکیج فقط از طریق درگاه بانکی امکانپذیر است.
|
||||
</MudAlert>
|
||||
}
|
||||
|
||||
<MudButton Variant="Variant.Text" Color="Color.Default" FullWidth="true" OnClick="ClosePurchaseOptions">
|
||||
بستن
|
||||
|
||||
@@ -45,6 +45,7 @@ public partial class Index
|
||||
// Purchase Options Bottom Sheet
|
||||
private bool _showPurchaseBottomSheet;
|
||||
private bool _isProcessingPayment;
|
||||
private int _purchaseCycleCount; // تعداد دورهای خرید — اگر > 0 فقط IPG مجاز
|
||||
|
||||
// Dashboard Tiles
|
||||
private readonly List<DashTile> _dashTiles = new()
|
||||
@@ -148,6 +149,11 @@ public partial class Index
|
||||
var discount = FormatPrice(b.DiscountBalance);
|
||||
_walletNetwork = FormatPrice(b.NetworkBalance);
|
||||
_walletDiscount = discount;
|
||||
|
||||
// بارگذاری تعداد دورهای خرید برای کنترل روشهای پرداخت
|
||||
var magicStatus = await WalletService.GetMagicWalletStatusAsync();
|
||||
_purchaseCycleCount = magicStatus.PurchaseCycleCount;
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace FrontOffice.Main.Pages.Profile;
|
||||
|
||||
public partial class MagicWallet : ComponentBase
|
||||
{
|
||||
private MagicWalletStatus _status = new(0, 0, 0, 0, 0, 0, null);
|
||||
private MagicWalletStatus _status = new(0, 0, 0, 0, 0, 0, null, 0);
|
||||
private bool _isLoading = true;
|
||||
private bool _isProcessing;
|
||||
private long _chargeAmount;
|
||||
|
||||
@@ -38,6 +38,17 @@
|
||||
درخواستهای برداشت
|
||||
</MudButton>
|
||||
|
||||
<!-- دکمه شارژ کیفپول اعتباری -->
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Info"
|
||||
Size="Size.Large"
|
||||
FullWidth="true"
|
||||
StartIcon="@Icons.Material.Filled.CreditCard"
|
||||
Href="@RouteConstants.Profile.ChargeDiscountWallet"
|
||||
Class="rounded-lg">
|
||||
شارژ کیفپول اعتباری
|
||||
</MudButton>
|
||||
|
||||
<MudPaper Elevation="2" Class="pa-4 rounded-lg">
|
||||
<MudText Typo="Typo.h6" Class="mb-2">تراکنشها و مسیرهای شارژ</MudText>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ public static class RouteConstants
|
||||
public const string Tree = "/profile/tree";
|
||||
public const string Wallet = "/profile/wallet";
|
||||
public const string MagicWallet = "/profile/magic-wallet";
|
||||
public const string ChargeDiscountWallet = "/profile/charge-discount-wallet";
|
||||
public const string WithdrawalRequests = "/profile/withdrawal-requests";
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ public record MagicWalletStatus(
|
||||
long MagicMaxDeposit,
|
||||
long MagicRemainingDeposit,
|
||||
long Balance,
|
||||
DateTime? MagicActivatedAt
|
||||
DateTime? MagicActivatedAt,
|
||||
int PurchaseCycleCount
|
||||
);
|
||||
|
||||
public class WalletService
|
||||
@@ -212,12 +213,13 @@ public class WalletService
|
||||
response.MagicMaxDeposit,
|
||||
response.MagicRemainingDeposit,
|
||||
response.Balance,
|
||||
activatedAt
|
||||
activatedAt,
|
||||
response.PurchaseCycleCount
|
||||
);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new MagicWalletStatus(0, 0, 0, 0, 0, 0, null);
|
||||
return new MagicWalletStatus(0, 0, 0, 0, 0, 0, null, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,6 +243,26 @@ public class WalletService
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Success, string? GatewayUrl, string? Error)> InitiateDiscountChargeAsync(long amount)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _client.InitiateDiscountChargeAsync(new InitiateDiscountChargeRequest
|
||||
{
|
||||
Amount = amount
|
||||
});
|
||||
|
||||
if (response.IsSuccess)
|
||||
return (true, response.GatewayUrl, null);
|
||||
|
||||
return (false, null, response.ErrorMessage);
|
||||
}
|
||||
catch (Grpc.Core.RpcException ex)
|
||||
{
|
||||
return (false, null, ex.Status.Detail ?? "خطا در ارتباط با سرور");
|
||||
}
|
||||
}
|
||||
|
||||
public int GetWalletMode()
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user