Merge branch 'kub-stage' into production
Build and Deploy to Production / build-and-deploy (push) Successful in 4m15s
Build and Deploy to Production / build-and-deploy (push) Successful in 4m15s
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
##
|
##
|
||||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.rsuser
|
*.rsuser
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
# Docs moved to totalDoc
|
# Docs moved to totalDoc
|
||||||
|
|
||||||
See [totalDoc/INDEX.md](../../totalDoc/INDEX.md) for all documentation.
|
See [totalDoc/INDEX.md](../../totalDoc/INDEX.md) for all documentation.
|
||||||
|
|
||||||
@@ -101,7 +101,6 @@
|
|||||||
| 6.6 | `UserOrderContract.SubmitShopBuyOrder` | `UserOrderContract` | `/checkout-summary` | ثبت سفارش و پرداخت از کیف پول |
|
| 6.6 | `UserOrderContract.SubmitShopBuyOrder` | `UserOrderContract` | `/checkout-summary` | ثبت سفارش و پرداخت از کیف پول |
|
||||||
| 6.7 | `OrderService.GetOrdersAsync` | `UserOrderContract.GetCustomerOrders` | `/orders` | لیست سفارشهای کاربر |
|
| 6.7 | `OrderService.GetOrdersAsync` | `UserOrderContract.GetCustomerOrders` | `/orders` | لیست سفارشهای کاربر |
|
||||||
| 6.8 | `OrderService.GetOrderAsync` | `UserOrderContract.GetCustomerOrder` | `/order/{id}`, `/order-tracking/{id}` | جزئیات یک سفارش |
|
| 6.8 | `OrderService.GetOrderAsync` | `UserOrderContract.GetCustomerOrder` | `/order/{id}`, `/order-tracking/{id}` | جزئیات یک سفارش |
|
||||||
| 6.9 | `OrderService.CalculateOrderPVAsync` | `UserOrderContract.CalculateOrderPV` | `/order/{id}` | محاسبه PV سفارش |
|
|
||||||
| 6.10 | `VATService.GetRateAsync` | `UserOrderContract` (via scope) | Store/Discount صفحات قیمت | نرخ مالیات بر ارزش افزوده (کش روزانه) |
|
| 6.10 | `VATService.GetRateAsync` | `UserOrderContract` (via scope) | Store/Discount صفحات قیمت | نرخ مالیات بر ارزش افزوده (کش روزانه) |
|
||||||
| 6.11 | `WalletService.GetBalancesAsync` | `UserWalletContract` | `/checkout-summary` | بررسی موجودی برای پرداخت سفارش |
|
| 6.11 | `WalletService.GetBalancesAsync` | `UserWalletContract` | `/checkout-summary` | بررسی موجودی برای پرداخت سفارش |
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
|
<PackageReference Include="DateTimeConverterCL" Version="1.0.0" />
|
||||||
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf -->
|
<!-- Replace all FrontOffice.BFF protobuf packages with CMS protobuf (CI/CD packs → Nexus) -->
|
||||||
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.204" />
|
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.211" />
|
||||||
<!-- <ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />-->
|
|
||||||
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
<PackageReference Include="MudBlazor" Version="8.14.0" />
|
||||||
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
|||||||
@@ -22,9 +22,11 @@
|
|||||||
else if (_addresses.Count == 0)
|
else if (_addresses.Count == 0)
|
||||||
{
|
{
|
||||||
<MudAlert Severity="Severity.Warning">
|
<MudAlert Severity="Severity.Warning">
|
||||||
هیچ آدرسی ثبت نشده است. لطفاً از بخش پروفایل آدرس خود را اضافه کنید.
|
هیچ آدرسی ثبت نشده است. میتوانید همینجا آدرس جدید اضافه کنید.
|
||||||
</MudAlert>
|
</MudAlert>
|
||||||
<MudButton Class="mt-2" Variant="Variant.Outlined" Href="/profile/addresses">افزودن آدرس</MudButton>
|
<MudButton Class="mt-2" Variant="Variant.Outlined" Color="Color.Primary"
|
||||||
|
StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
OnClick="OpenAddAddressDialog">افزودن آدرس</MudButton>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -41,13 +43,25 @@
|
|||||||
<MudText Typo="Typo.subtitle2">@address.Title</MudText>
|
<MudText Typo="Typo.subtitle2">@address.Title</MudText>
|
||||||
<MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText>
|
<MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
@if (address.IsDefault)
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
|
||||||
{
|
@if (address.IsDefault)
|
||||||
<MudChip T="string" Color="Color.Success" Variant="Variant.Outlined">پیشفرض</MudChip>
|
{
|
||||||
}
|
<MudChip T="string" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Small">پیشفرض</MudChip>
|
||||||
|
}
|
||||||
|
<span @onclick:stopPropagation="true">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Edit"
|
||||||
|
Size="Size.Small"
|
||||||
|
Color="Color.Primary"
|
||||||
|
aria-label="ویرایش آدرس"
|
||||||
|
OnClick="@(() => OpenEditAddressDialog(address))" />
|
||||||
|
</span>
|
||||||
|
</MudStack>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
}
|
}
|
||||||
|
<MudButton Class="mt-2" Variant="Variant.Text" Color="Color.Primary"
|
||||||
|
StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
OnClick="OpenAddAddressDialog">افزودن آدرس جدید</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
}
|
}
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
||||||
|
using FrontOffice.Main.Pages.Profile.Components;
|
||||||
using FrontOffice.Main.Utilities;
|
using FrontOffice.Main.Utilities;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
@@ -61,12 +62,14 @@ public partial class Checkout
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_addresses = new();
|
_addresses = new();
|
||||||
|
_selectedAddress = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"خطا در بارگذاری آدرسها: {ex.Message}", Severity.Error);
|
Snackbar.Add($"خطا در بارگذاری آدرسها: {ex.Message}", Severity.Error);
|
||||||
_addresses = new();
|
_addresses = new();
|
||||||
|
_selectedAddress = null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -75,6 +78,30 @@ public partial class Checkout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OpenAddAddressDialog()
|
||||||
|
{
|
||||||
|
var dialog = await DialogService.ShowAsync<AddAddressDialog>("افزودن آدرس جدید");
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (result is { Canceled: false })
|
||||||
|
{
|
||||||
|
await AuthService.RefreshTokenAsync();
|
||||||
|
await LoadAddresses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OpenEditAddressDialog(CustomerAddressModel address)
|
||||||
|
{
|
||||||
|
var dialog = await DialogService.ShowAsync<EditAddressDialog>("ویرایش آدرس", new DialogParameters<EditAddressDialog>
|
||||||
|
{
|
||||||
|
{ x => x.Model, address }
|
||||||
|
});
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (result is { Canceled: false })
|
||||||
|
{
|
||||||
|
await LoadAddresses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PlaceOrder()
|
private async Task PlaceOrder()
|
||||||
{
|
{
|
||||||
if (!CanPlaceOrder || _selectedAddress is null)
|
if (!CanPlaceOrder || _selectedAddress is null)
|
||||||
|
|||||||
@@ -52,29 +52,47 @@
|
|||||||
<div id="org-chart-container" class="org-chart-container"></div>
|
<div id="org-chart-container" class="org-chart-container"></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@* Stats Bar *@
|
@* Stats Bar — فقط آمار خود کاربر (نه نودهای درخت) *@
|
||||||
@if (_statistics != null && !_isLoading)
|
@if (_statistics != null && !_isLoading)
|
||||||
{
|
{
|
||||||
<div class="org-chart-stats">
|
<div class="org-chart-stats">
|
||||||
<div class="stat-item">
|
<div class="org-chart-stats-row">
|
||||||
<span class="stat-label">کل اعضا:</span>
|
<div class="stat-item">
|
||||||
<span class="stat-value">@_statistics.TotalMembers</span>
|
<span class="stat-label">کل اعضا:</span>
|
||||||
|
<span class="stat-value">@_statistics.TotalMembers</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<span class="stat-label">سازمان چپ:</span>
|
||||||
|
<span class="stat-value left">@_statistics.LeftLegCount</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<span class="stat-label">سازمان راست:</span>
|
||||||
|
<span class="stat-value right">@_statistics.RightLegCount</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<span class="stat-label">عمق:</span>
|
||||||
|
<span class="stat-value">@_statistics.TreeDepth</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<span class="stat-label">پای ضعیف:</span>
|
||||||
|
<span class="stat-value">@(_statistics.WeakerLeg == "Left" ? "چپ" : "راست")</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-item">
|
<div class="org-chart-stats-row leg-scores">
|
||||||
<span class="stat-label">سازمان چپ:</span>
|
<div class="stat-item leg-score-gold">
|
||||||
<span class="stat-value left">@_statistics.LeftLegCount</span>
|
<span class="stat-label">پکیج طلایی:</span>
|
||||||
|
<span class="stat-value left">چپ @_statistics.GoldLeftLegTotal</span>
|
||||||
|
<span class="stat-sep">·</span>
|
||||||
|
<span class="stat-value right">راست @_statistics.GoldRightLegTotal</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-item">
|
<div class="org-chart-stats-row leg-scores">
|
||||||
<span class="stat-label">سازمان راست:</span>
|
<div class="stat-item leg-score-silver">
|
||||||
<span class="stat-value right">@_statistics.RightLegCount</span>
|
<span class="stat-label">پکیج نقرهای:</span>
|
||||||
</div>
|
<span class="stat-value left">چپ @_statistics.SilverLeftLegTotal</span>
|
||||||
<div class="stat-item">
|
<span class="stat-sep">·</span>
|
||||||
<span class="stat-label">عمق:</span>
|
<span class="stat-value right">راست @_statistics.SilverRightLegTotal</span>
|
||||||
<span class="stat-value">@_statistics.TreeDepth</span>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="stat-label">پای ضعیف:</span>
|
|
||||||
<span class="stat-value">@(_statistics.WeakerLeg == "Left" ? "چپ" : "راست")</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using DateTimeConverterCL;
|
||||||
using FrontOffice.Main.Utilities;
|
using FrontOffice.Main.Utilities;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
@@ -108,7 +109,9 @@ public partial class OrganizationChart : IAsyncDisposable
|
|||||||
isActive = n.IsActive,
|
isActive = n.IsActive,
|
||||||
isClubActive = n.IsClubActive,
|
isClubActive = n.IsClubActive,
|
||||||
activationWeekNumber = n.ActivationWeekNumber,
|
activationWeekNumber = n.ActivationWeekNumber,
|
||||||
joinedAt = n.JoinedAt,
|
registeredAt = n.JoinedAt.HasValue
|
||||||
|
? n.JoinedAt.Value.ToLocalTime().MiladiToJalali()
|
||||||
|
: "",
|
||||||
referralCode = n.ReferralCode,
|
referralCode = n.ReferralCode,
|
||||||
packageName = n.PackageName ?? string.Empty
|
packageName = n.PackageName ?? string.Empty
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|||||||
@@ -21,9 +21,11 @@
|
|||||||
else if (_addresses.Count == 0)
|
else if (_addresses.Count == 0)
|
||||||
{
|
{
|
||||||
<MudAlert Severity="Severity.Warning">
|
<MudAlert Severity="Severity.Warning">
|
||||||
هیچ آدرسی ثبت نشده است. لطفاً از بخش پروفایل آدرس خود را اضافه کنید.
|
هیچ آدرسی ثبت نشده است. میتوانید همینجا آدرس جدید اضافه کنید.
|
||||||
</MudAlert>
|
</MudAlert>
|
||||||
<MudButton Class="mt-2" Variant="Variant.Outlined" Href="/profile/addresses">افزودن آدرس</MudButton>
|
<MudButton Class="mt-2" Variant="Variant.Outlined" Color="Color.Primary"
|
||||||
|
StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
OnClick="OpenAddAddressDialog">افزودن آدرس</MudButton>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -40,13 +42,25 @@
|
|||||||
<MudText Typo="Typo.subtitle2">@address.Title</MudText>
|
<MudText Typo="Typo.subtitle2">@address.Title</MudText>
|
||||||
<MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText>
|
<MudText Typo="Typo.body2" Class="mud-text-secondary">@address.Address</MudText>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
@if (address.IsDefault)
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
|
||||||
{
|
@if (address.IsDefault)
|
||||||
<MudChip T="string" Color="Color.Success" Variant="Variant.Outlined">پیشفرض</MudChip>
|
{
|
||||||
}
|
<MudChip T="string" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Small">پیشفرض</MudChip>
|
||||||
|
}
|
||||||
|
<span @onclick:stopPropagation="true">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Edit"
|
||||||
|
Size="Size.Small"
|
||||||
|
Color="Color.Primary"
|
||||||
|
aria-label="ویرایش آدرس"
|
||||||
|
OnClick="@(() => OpenEditAddressDialog(address))" />
|
||||||
|
</span>
|
||||||
|
</MudStack>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
}
|
}
|
||||||
|
<MudButton Class="mt-2" Variant="Variant.Text" Color="Color.Primary"
|
||||||
|
StartIcon="@Icons.Material.Filled.Add"
|
||||||
|
OnClick="OpenAddAddressDialog">افزودن آدرس جدید</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
}
|
}
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
using CMSMicroservice.Protobuf.Protos.UserAddress;
|
||||||
using CMSMicroservice.Protobuf.Protos.UserOrder;
|
using CMSMicroservice.Protobuf.Protos.UserOrder;
|
||||||
|
using FrontOffice.Main.Pages.Profile.Components;
|
||||||
using FrontOffice.Main.Shared;
|
using FrontOffice.Main.Shared;
|
||||||
using FrontOffice.Main.Utilities;
|
using FrontOffice.Main.Utilities;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
@@ -72,12 +73,14 @@ public partial class CheckoutSummary : ComponentBase
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_addresses = new();
|
_addresses = new();
|
||||||
|
_selectedAddress = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Snackbar.Add($"خطا در بارگذاری آدرسها: {ex.Message}", Severity.Error);
|
Snackbar.Add($"خطا در بارگذاری آدرسها: {ex.Message}", Severity.Error);
|
||||||
_addresses = new();
|
_addresses = new();
|
||||||
|
_selectedAddress = null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -86,6 +89,30 @@ public partial class CheckoutSummary : ComponentBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OpenAddAddressDialog()
|
||||||
|
{
|
||||||
|
var dialog = await DialogService.ShowAsync<AddAddressDialog>("افزودن آدرس جدید");
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (result is { Canceled: false })
|
||||||
|
{
|
||||||
|
await AuthService.RefreshTokenAsync();
|
||||||
|
await LoadAddresses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OpenEditAddressDialog(CustomerAddressModel address)
|
||||||
|
{
|
||||||
|
var dialog = await DialogService.ShowAsync<EditAddressDialog>("ویرایش آدرس", new DialogParameters<EditAddressDialog>
|
||||||
|
{
|
||||||
|
{ x => x.Model, address }
|
||||||
|
});
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (result is { Canceled: false })
|
||||||
|
{
|
||||||
|
await LoadAddresses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PlaceOrder()
|
private async Task PlaceOrder()
|
||||||
{
|
{
|
||||||
if (!CanPlaceOrder || _selectedAddress is null)
|
if (!CanPlaceOrder || _selectedAddress is null)
|
||||||
|
|||||||
@@ -112,30 +112,6 @@ else
|
|||||||
</MudStack>
|
</MudStack>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@* نمایش PV سفارش *@
|
|
||||||
@if (_pvData != null && _pvData.TotalPv > 0)
|
|
||||||
{
|
|
||||||
<MudDivider Class="my-2" />
|
|
||||||
<MudStack Spacing="1" Class="pa-2" Style="background-color: var(--mud-palette-background-grey); border-radius: 8px;">
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
|
|
||||||
<MudIcon Icon="@Icons.Material.Filled.TrendingUp" Color="Color.Info" Size="Size.Small" />
|
|
||||||
<MudText Typo="Typo.subtitle2" Color="Color.Info">امتیاز فروش (PV)</MudText>
|
|
||||||
</MudStack>
|
|
||||||
@foreach (var product in _pvData.Products)
|
|
||||||
{
|
|
||||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
|
||||||
<MudText Typo="Typo.caption" Class="mud-text-secondary">@product.ProductTitle × @product.Quantity</MudText>
|
|
||||||
<MudText Typo="Typo.caption">@string.Format("{0:N0}", product.TotalPv) PV</MudText>
|
|
||||||
</MudStack>
|
|
||||||
}
|
|
||||||
<MudDivider Class="my-1" />
|
|
||||||
<MudStack Row="true" Justify="Justify.SpaceBetween">
|
|
||||||
<MudText Typo="Typo.body2" Class="fw-bold">جمع PV:</MudText>
|
|
||||||
<MudText Typo="Typo.body2" Color="Color.Info" Class="fw-bold">@string.Format("{0:N0}", _pvData.TotalPv) PV</MudText>
|
|
||||||
</MudStack>
|
|
||||||
</MudStack>
|
|
||||||
}
|
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudContainer>
|
</MudContainer>
|
||||||
|
|||||||
@@ -12,17 +12,12 @@ public partial class OrderDetail : ComponentBase
|
|||||||
[Parameter] public long id { get; set; }
|
[Parameter] public long id { get; set; }
|
||||||
|
|
||||||
private GetUserOrderResponse? _order;
|
private GetUserOrderResponse? _order;
|
||||||
private CalculateOrderPVResponse? _pvData;
|
|
||||||
private bool _loading;
|
private bool _loading;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
_loading = true;
|
_loading = true;
|
||||||
_order = await OrderService.GetOrderAsync(id);
|
_order = await OrderService.GetOrderAsync(id);
|
||||||
if (_order != null)
|
|
||||||
{
|
|
||||||
_pvData = await OrderService.CalculateOrderPVAsync(id);
|
|
||||||
}
|
|
||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,4 +47,3 @@ public partial class OrderDetail : ComponentBase
|
|||||||
private static string GetProductImageUrl(string? imageUrl)
|
private static string GetProductImageUrl(string? imageUrl)
|
||||||
=> string.IsNullOrWhiteSpace(imageUrl) ? "/images/product-placeholder.svg" : imageUrl.TrimStart('/');
|
=> string.IsNullOrWhiteSpace(imageUrl) ? "/images/product-placeholder.svg" : imageUrl.TrimStart('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class NetworkNodeDto
|
|||||||
public NetworkNodeDto? RightChild { get; set; }
|
public NetworkNodeDto? RightChild { get; set; }
|
||||||
public int Level { get; set; }
|
public int Level { get; set; }
|
||||||
public bool IsActive { get; set; } = true;
|
public bool IsActive { get; set; } = true;
|
||||||
public DateTime? JoinedAt { get; set; }
|
public DateTime? JoinedAt { get; set; } // تاریخ ثبتنام (UserCreated)
|
||||||
public bool IsClubActive { get; set; }
|
public bool IsClubActive { get; set; }
|
||||||
public string? ActivationWeekNumber { get; set; }
|
public string? ActivationWeekNumber { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -26,6 +26,18 @@ public class NetworkNodeDto
|
|||||||
/// نام پکیج موثر (مثلاً پکیج طلایی / نقرهای)
|
/// نام پکیج موثر (مثلاً پکیج طلایی / نقرهای)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PackageName { get; set; }
|
public string? PackageName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>تعداد اعضای فعال با پکیج طلایی جاری در پای چپ</summary>
|
||||||
|
public int GoldLeftLegTotal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>تعداد اعضای فعال با پکیج طلایی جاری در پای راست</summary>
|
||||||
|
public int GoldRightLegTotal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>تعداد اعضای فعال با پکیج نقرهای جاری در پای چپ</summary>
|
||||||
|
public int SilverLeftLegTotal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>تعداد اعضای فعال با پکیج نقرهای جاری در پای راست</summary>
|
||||||
|
public int SilverRightLegTotal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -53,6 +65,11 @@ public class FlatNetworkNodeDto
|
|||||||
/// نام پکیج موثر (مثلاً پکیج طلایی / نقرهای)
|
/// نام پکیج موثر (مثلاً پکیج طلایی / نقرهای)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PackageName { get; set; }
|
public string? PackageName { get; set; }
|
||||||
|
|
||||||
|
public int GoldLeftLegTotal { get; set; }
|
||||||
|
public int GoldRightLegTotal { get; set; }
|
||||||
|
public int SilverLeftLegTotal { get; set; }
|
||||||
|
public int SilverRightLegTotal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -92,7 +109,11 @@ public class NetworkTreeDto
|
|||||||
ActivationWeekNumber = node.ActivationWeekNumber,
|
ActivationWeekNumber = node.ActivationWeekNumber,
|
||||||
JoinedAt = node.JoinedAt,
|
JoinedAt = node.JoinedAt,
|
||||||
ReferralCode = node.ReferralCode,
|
ReferralCode = node.ReferralCode,
|
||||||
PackageName = node.PackageName
|
PackageName = node.PackageName,
|
||||||
|
GoldLeftLegTotal = node.GoldLeftLegTotal,
|
||||||
|
GoldRightLegTotal = node.GoldRightLegTotal,
|
||||||
|
SilverLeftLegTotal = node.SilverLeftLegTotal,
|
||||||
|
SilverRightLegTotal = node.SilverRightLegTotal
|
||||||
};
|
};
|
||||||
|
|
||||||
result.Add(flatNode);
|
result.Add(flatNode);
|
||||||
@@ -125,10 +146,19 @@ public class LastMemberDto
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class NetworkStatisticsDto
|
public class NetworkStatisticsDto
|
||||||
{
|
{
|
||||||
|
/// <summary>اعضای فعال باشگاه در پای چپ</summary>
|
||||||
public int LeftLegCount { get; set; }
|
public int LeftLegCount { get; set; }
|
||||||
|
/// <summary>اعضای فعال باشگاه در پای راست</summary>
|
||||||
public int RightLegCount { get; set; }
|
public int RightLegCount { get; set; }
|
||||||
|
/// <summary>LeftLegCount + RightLegCount</summary>
|
||||||
public int TotalMembers { get; set; }
|
public int TotalMembers { get; set; }
|
||||||
public int TreeDepth { get; set; }
|
public int TreeDepth { get; set; }
|
||||||
public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right"
|
public string WeakerLeg { get; set; } = string.Empty; // "Left" or "Right"
|
||||||
public LastMemberDto? LastMember { get; set; }
|
public LastMemberDto? LastMember { get; set; }
|
||||||
|
|
||||||
|
/// <summary>تعداد اعضای فعال با پکیج طلایی/نقرهای جاری در هر پا — نوار پایین شجره</summary>
|
||||||
|
public int GoldLeftLegTotal { get; set; }
|
||||||
|
public int GoldRightLegTotal { get; set; }
|
||||||
|
public int SilverLeftLegTotal { get; set; }
|
||||||
|
public int SilverRightLegTotal { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,10 @@ public class NetworkMembershipService
|
|||||||
TotalMembers = response.TotalMembers,
|
TotalMembers = response.TotalMembers,
|
||||||
TreeDepth = response.MaxDepth,
|
TreeDepth = response.MaxDepth,
|
||||||
WeakerLeg = response.WeakerLeg,
|
WeakerLeg = response.WeakerLeg,
|
||||||
|
GoldLeftLegTotal = response.GoldLeftLegTotal,
|
||||||
|
GoldRightLegTotal = response.GoldRightLegTotal,
|
||||||
|
SilverLeftLegTotal = response.SilverLeftLegTotal,
|
||||||
|
SilverRightLegTotal = response.SilverRightLegTotal,
|
||||||
LastMember = response.LastMember != null ? new LastMemberDto
|
LastMember = response.LastMember != null ? new LastMemberDto
|
||||||
{
|
{
|
||||||
UserId = response.LastMember.UserId,
|
UserId = response.LastMember.UserId,
|
||||||
@@ -138,8 +142,13 @@ public class NetworkMembershipService
|
|||||||
IsClubActive = node.IsClubActive,
|
IsClubActive = node.IsClubActive,
|
||||||
ReferralCode = node.ReferralCode,
|
ReferralCode = node.ReferralCode,
|
||||||
PackageName = string.IsNullOrWhiteSpace(node.PackageName) ? null : node.PackageName,
|
PackageName = string.IsNullOrWhiteSpace(node.PackageName) ? null : node.PackageName,
|
||||||
|
GoldLeftLegTotal = node.GoldLeftLegTotal,
|
||||||
|
GoldRightLegTotal = node.GoldRightLegTotal,
|
||||||
|
SilverLeftLegTotal = node.SilverLeftLegTotal,
|
||||||
|
SilverRightLegTotal = node.SilverRightLegTotal,
|
||||||
ActivationWeekNumber = node.ActivationWeekDefinitionId?.ToString(),
|
ActivationWeekNumber = node.ActivationWeekDefinitionId?.ToString(),
|
||||||
JoinedAt = node.JoinedAt?.ToDateTime(),
|
JoinedAt = node.UserCreated?.ToDateTime()
|
||||||
|
?? node.JoinedAt?.ToDateTime(),
|
||||||
LeftChild = MapNodeFromProto(node.LeftChild),
|
LeftChild = MapNodeFromProto(node.LeftChild),
|
||||||
RightChild = MapNodeFromProto(node.RightChild)
|
RightChild = MapNodeFromProto(node.RightChild)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -97,22 +97,4 @@ public class OrderService
|
|||||||
return 0.10;
|
return 0.10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// محاسبه PV سفارش
|
|
||||||
/// </summary>
|
|
||||||
public async Task<CalculateOrderPVResponse?> CalculateOrderPVAsync(long orderId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await _userOrderContractClient.CalculateOrderPVAsync(new CalculateOrderPVRequest
|
|
||||||
{
|
|
||||||
OrderId = orderId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -118,6 +118,16 @@
|
|||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.node-registered-at {
|
||||||
|
font-size: 8px;
|
||||||
|
color: #6c757d;
|
||||||
|
margin-top: 1px;
|
||||||
|
line-height: 1.2;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.node-level-sm {
|
.node-level-sm {
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
@@ -141,6 +151,7 @@
|
|||||||
max-width: 120px;
|
max-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* D3: تعداد پکیج طلایی/نقرهای فقط در نوار پایین شجره (.org-chart-stats) */
|
||||||
/* Referral Code - only for club active members */
|
/* Referral Code - only for club active members */
|
||||||
.node-referral {
|
.node-referral {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -370,14 +381,27 @@
|
|||||||
/* Stats Bar */
|
/* Stats Bar */
|
||||||
.org-chart-stats {
|
.org-chart-stats {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 24px;
|
gap: 8px;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
border-top: 1px solid #e9ecef;
|
border-top: 1px solid #e9ecef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.org-chart-stats-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-chart-stats-row.leg-scores {
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-item {
|
.stat-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -385,6 +409,21 @@
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-item.leg-score-gold .stat-label {
|
||||||
|
color: #b8860b;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item.leg-score-silver .stat-label {
|
||||||
|
color: #607d8b;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-sep {
|
||||||
|
color: #adb5bd;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
}
|
}
|
||||||
@@ -448,10 +487,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.org-chart-stats {
|
.org-chart-stats {
|
||||||
flex-wrap: wrap;
|
gap: 8px;
|
||||||
gap: 12px;
|
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.org-chart-stats-row {
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-item {
|
.stat-item {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ window.OrgChart = {
|
|||||||
.container('#' + containerId)
|
.container('#' + containerId)
|
||||||
.data(data)
|
.data(data)
|
||||||
.nodeWidth((d) => 140)
|
.nodeWidth((d) => 140)
|
||||||
.nodeHeight((d) => 85)
|
.nodeHeight((d) => 98)
|
||||||
.childrenMargin((d) => 50)
|
.childrenMargin((d) => 50)
|
||||||
.compactMarginBetween((d) => 15)
|
.compactMarginBetween((d) => 15)
|
||||||
.compactMarginPair((d) => 15)
|
.compactMarginPair((d) => 15)
|
||||||
@@ -86,6 +86,7 @@ window.OrgChart = {
|
|||||||
<div class="node-avatar-sm">${firstChar}</div>
|
<div class="node-avatar-sm">${firstChar}</div>
|
||||||
<div class="node-info">
|
<div class="node-info">
|
||||||
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
|
<div class="node-name-sm">${data.fullName || 'بدون نام'}</div>
|
||||||
|
${data.registeredAt ? `<div class="node-registered-at">${data.registeredAt}</div>` : ''}
|
||||||
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
|
<div class="node-level-sm">L${data.level || 0}${!isRoot ? ' • ' + (data.position === 'Left' ? 'چپ' : 'راست') : ''}</div>
|
||||||
${packageBadge}
|
${packageBadge}
|
||||||
${referralCodeHtml}
|
${referralCodeHtml}
|
||||||
@@ -296,7 +297,7 @@ window.OrgChart = {
|
|||||||
isActive: node.isActive !== false,
|
isActive: node.isActive !== false,
|
||||||
isClubActive: node.isClubActive || false,
|
isClubActive: node.isClubActive || false,
|
||||||
activationWeekNumber: node.activationWeekNumber,
|
activationWeekNumber: node.activationWeekNumber,
|
||||||
joinedAt: node.joinedAt
|
registeredAt: node.registeredAt || node.joinedAt || ''
|
||||||
};
|
};
|
||||||
|
|
||||||
result.push(flatNode);
|
result.push(flatNode);
|
||||||
|
|||||||
Reference in New Issue
Block a user