diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj
index 1eb7033..1c7b056 100644
--- a/src/BackOffice/BackOffice.csproj
+++ b/src/BackOffice/BackOffice.csproj
@@ -138,7 +138,7 @@
-
+
diff --git a/src/BackOffice/Pages/Commission/Dashboard.razor b/src/BackOffice/Pages/Commission/Dashboard.razor
index 4af9e73..35b043d 100644
--- a/src/BackOffice/Pages/Commission/Dashboard.razor
+++ b/src/BackOffice/Pages/Commission/Dashboard.razor
@@ -5,152 +5,89 @@
@using MudBlazor
@using BackOffice.Pages.AutoComplete
-
-
داشبورد کمیسیون
+
- @* ── G11: راهنمای کمیسیون (Q28) ── *@
-
- هر پکیج Pool پورسانت مستقل دارد. مبالغ ActivationFee به Pool پکیج مربوطه واریز میشود.
-
+ @* ── عنوان صفحه ── *@
+
+ داشبورد کمیسیون
+
+ مبلغ پورسانت هر هفته بین اعضاء تقسیم میشود. هر پکیج استخر مستقل دارد.
+
+
- @if (_isLoading)
- {
-
- }
- else
- {
-
-
-
-
-
- استخر هفتگی
- @(_poolData?.TotalPoolAmount.ToString("N0") ?? "0") تومان
- @_currentWeekDisplayText
-
-
-
-
-
-
-
- تعداد تعادلها
- @(_poolData?.TotalBalances.ToString("N0") ?? "0")
- مجموع تعادل های فعال
-
-
-
-
-
-
-
- ارزش هر تعادل
- @(_poolData?.ValuePerBalance.ToString("N0") ?? "0") تومان
- قیمت واحد تعادل
-
-
-
-
-
-
-
-
- وضعیت محاسبه
-
-
- @(_poolData?.IsCalculated == true ? "محاسبه شده ✓" : "محاسبه نشده ✗")
-
-
- @if (_poolData?.CalculatedAt != null)
- {
- var calculatedDate = _poolData.CalculatedAt.ToDateTime().ToLocalTime();
- var persianDate = PersianDateTime.ConvertToPersianDateTime(calculatedDate);
- @($"در تاریخ {persianDate}")
- }
- else
- {
- @("در انتظار محاسبه")
- }
-
-
-
-
-
-
-
-
-
- انتخاب هفته:
-
+ @* ── فیلتر (اول از همه) ── *@
+
+
+
@if (_allWeeks.Any())
{
-
-
+
+
@if (_availableWeeks?.CurrentWeek != null)
{
-
-
- @_availableWeeks.CurrentWeek.DisplayText
-
+
+
+ @_availableWeeks.CurrentWeek.DisplayText
+ جاری
+
}
-
+
@if (_availableWeeks?.CalculatedWeeks?.Any() == true)
{
- هفتههای محاسبه شده
+ تسویهشده
@foreach (var week in _availableWeeks.CalculatedWeeks)
{
-
-
- @week.DisplayText
+
+
+ @week.DisplayText
@if (week.TotalPoolAmount > 0)
{
-
- @week.TotalPoolAmount.ToString("N0") تومان
-
+ (@week.TotalPoolAmount.ToString("N0") T)
}
-
+
}
}
-
+
@if (_availableWeeks?.PendingWeeks?.Any() == true)
{
- هفتههای محاسبه نشده
+ در انتظار تسویه
@foreach (var week in _availableWeeks.PendingWeeks)
{
-
-
- @week.DisplayText
-
+
+
+ @week.DisplayText
+
}
}
-
+
@if (_availableWeeks?.FutureWeeks?.Any() == true)
{
هفتههای آینده
@foreach (var week in _availableWeeks.FutureWeeks)
{
-
-
- @week.DisplayText
-
+
+
+ @week.DisplayText
+
}
}
@@ -160,114 +97,222 @@
{
لیست هفتهها بارگذاری نشده
}
+
+
-
-
- بارگذاری
-
-
-
+
-
- @if (_poolData != null)
- {
-
- جزئیات استخر
-
-
-
- | شناسه استخر: |
- @_poolData.Id |
-
-
- | پکیج: |
-
- @if (!string.IsNullOrEmpty(_poolData.PackageTitle))
- {
- @_poolData.PackageTitle
- }
- else
- {
- -
- }
- |
-
-
- | شماره هفته: |
- @_currentWeekDisplayName |
-
-
- | مجموع استخر: |
- @_poolData.TotalPoolAmount.ToString("N0") تومان |
-
-
- | تعداد تعادل: |
- @_poolData.TotalBalances |
-
-
- | ارزش هر تعادل: |
- @_poolData.ValuePerBalance.ToString("N0") تومان |
-
-
- | وضعیت: |
-
-
- @(_poolData.IsCalculated ? "محاسبه شده" : "محاسبه نشده")
-
- |
-
-
- | تاریخ محاسبه: |
-
- @if (_poolData.CalculatedAt != null)
- {
- @_poolData.CalculatedAt.ToDateTime().ToLocalTime().MiladiToJalaliWithTime()
- }
- else
- {
- -
- }
- |
-
-
- | تاریخ ایجاد: |
- @_poolData.Created.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() |
-
-
-
-
- }
+
+
+ نمایش
+
+
+
+
-
-
- عملیات سریع
-
-
- مشاهده پرداختها
-
-
- درخواستهای برداشت
-
-
- اجرای محاسبه دستی
-
+ @* ── لودینگ ── *@
+ @if (_isLoading)
+ {
+
+
+
+ در حال بارگذاری اطلاعات استخر…
}
-
+ else
+ {
+ @* ── نوار وضعیت هفته / پکیج ── *@
+
+
+
+ @_currentWeekDisplayText
+
+ @if (!string.IsNullOrEmpty(_poolData?.PackageTitle))
+ {
+
+
+ @_poolData.PackageTitle
+
+ }
+
+
+
+ @if (_poolData != null && _poolData.Id > 0)
+ {
+ @if (_poolData.IsCalculated)
+ {
+
+ تسویه انجام شده
+
+ }
+ else
+ {
+
+ در انتظار تسویه
+
+ }
+ }
+
+
+
+ @* ── ۳ کارت اصلی ── *@
+
+ @* کارت ۱: کل مبلغ استخر *@
+
+
+
+
+
+ کل مبلغ استخر پورسانت
+
+
+ @((_poolData?.TotalPoolAmount ?? 0).ToString("N0"))
+
+ تومان — جمع کارمزد فعالسازیهای این هفته
+
+
+
+
+ @* کارت ۲: تعداد واحدهای پورسانت *@
+
+
+
+
+
+ واحدهای پورسانت (بالانس)
+
+
+
+
+
+ @((_poolData?.TotalBalances ?? 0).ToString("N0"))
+
+ واحد — مجموع همه اعضاء فعال
+
+
+
+
+ @* کارت ۳: سهم هر واحد *@
+
+
+
+
+
+ سهم پورسانت هر واحد
+
+
+ @((_poolData?.ValuePerBalance ?? 0).ToString("N0"))
+
+
+ تومان — @((_poolData?.IsCalculated == true) ? "قطعی شده" : "قطعی نشده")
+
+
+
+
+
+
+ @* ── اعتبارسنجی مبلغ استخر ── *@
+ @if (_poolData != null && _poolData.Id > 0)
+ {
+ @if (!_poolData.ValidationIsValid)
+ {
+
+ مبلغ استخر با تعداد فعالسازیهای دیتابیس مطابقت ندارد
+
+
+ مبلغ ثبتشده
+ @_poolData.TotalPoolAmount.ToString("N0") تومان
+
+
+ مبلغ انتظاری (@_poolData.ValidationActivationCount فعالسازی)
+ @_poolData.ValidationExpectedAmount.ToString("N0") تومان
+
+
+ اختلاف
+
+ @_poolData.ValidationDiscrepancy.ToString("N0") تومان
+
+
+
+
+ }
+ else if (_poolData.ValidationActivationCount > 0)
+ {
+
+ مبلغ استخر صحیح است — با @_poolData.ValidationActivationCount فعالسازی در این هفته مطابقت دارد.
+
+ }
+ }
+
+ @* ── جزئیات تکمیلی (بدون تکرار اطلاعات کارتها) ── *@
+ @if (_poolData != null && _poolData.Id > 0)
+ {
+
+
+
+
+
+ | شناسه استخر |
+ #@_poolData.Id |
+
+
+ | تاریخ ایجاد استخر |
+ @_poolData.Created.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() |
+
+ @if (_poolData.CalculatedAt != null)
+ {
+
+ | تاریخ تسویه |
+ @_poolData.CalculatedAt.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() |
+
+ }
+
+
+
+
+ }
+
+ @* ── دکمههای عملیاتی ── *@
+
+
+
+ پرداختهای این هفته
+
+
+ درخواستهای برداشت
+
+
+ @if (_poolData?.IsCalculated != true)
+ {
+
+ اجرای تسویه دستی
+
+ }
+
+
+ }
+
+
diff --git a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor
index 860cc13..ab841f7 100644
--- a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor
+++ b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor
@@ -169,6 +169,42 @@
+
+
+ @if (context.Item.IsNewActivation == null)
+ {
+ -
+ }
+ else if (context.Item.IsNewActivation == true)
+ {
+
+ عضو جدید
+
+ }
+ else
+ {
+
+ خرید مجدد
+
+ }
+
+
+
+
+
+ @if (!string.IsNullOrEmpty(context.Item.PackageName))
+ {
+
+ @context.Item.PackageName
+
+ }
+ else
+ {
+ -
+ }
+
+
+
@@ -337,7 +373,9 @@
isClubActive = n.IsClubActive,
isActivatedInTargetWeek = n.IsActivatedInTargetWeek,
activationWeekDefinitionId = n.ActivationWeekDefinitionId,
- clubActivatedAt = n.ClubActivatedAt?.ToDateTime().ToLocalTime().MiladiToJalali() ?? ""
+ clubActivatedAt = n.ClubActivatedAt?.ToDateTime().ToLocalTime().MiladiToJalali() ?? "",
+ isNewActivation = n.IsNewActivation,
+ packageName = n.PackageName ?? ""
}).ToArray();
var options = new { filterWeek = _activationWeekFilter };
diff --git a/src/BackOffice/wwwroot/css/admin-org-chart.css b/src/BackOffice/wwwroot/css/admin-org-chart.css
index c1c55fa..fe08397 100644
--- a/src/BackOffice/wwwroot/css/admin-org-chart.css
+++ b/src/BackOffice/wwwroot/css/admin-org-chart.css
@@ -94,8 +94,9 @@
.admin-node-card .node-meta {
display: flex;
align-items: center;
- gap: 6px;
- margin-top: 2px;
+ gap: 4px;
+ margin-top: 3px;
+ flex-wrap: wrap;
}
.admin-node-card .level-badge {
@@ -124,8 +125,8 @@
display: flex;
justify-content: space-between;
align-items: center;
- margin-top: 6px;
- padding-top: 6px;
+ margin-top: 5px;
+ padding-top: 5px;
border-top: 1px solid #f0f0f0;
font-size: 10px;
}
@@ -204,6 +205,48 @@
animation: pulse-highlight 1.5s ease-in-out infinite;
}
+/* نوع فعالسازی - inline pill */
+.admin-node-card .activation-pill {
+ display: inline-flex;
+ align-items: center;
+ padding: 1px 6px;
+ border-radius: 8px;
+ font-size: 9px;
+ font-weight: 600;
+ white-space: nowrap;
+ line-height: 1.4;
+}
+
+.admin-node-card .new-member-pill {
+ background: #e8f5e9;
+ color: #2e7d32;
+ border: 1px solid #a5d6a7;
+}
+
+.admin-node-card .renewal-pill {
+ background: #ede7f6;
+ color: #5e35b1;
+ border: 1px solid #b39ddb;
+}
+
+/* نام پکیج badge */
+.admin-node-card .package-name-badge {
+ display: inline-flex;
+ align-items: center;
+ height: 14px;
+ padding: 0 6px;
+ margin-top: 2px;
+ border-radius: 7px;
+ font-size: 9px;
+ color: #546e7a;
+ background: #eceff1;
+ border: 1px solid #b0bec5;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 120px;
+}
+
@keyframes pulse-highlight {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.8; }
diff --git a/src/BackOffice/wwwroot/js/admin-org-chart.js b/src/BackOffice/wwwroot/js/admin-org-chart.js
index 61c82e7..a78b038 100644
--- a/src/BackOffice/wwwroot/js/admin-org-chart.js
+++ b/src/BackOffice/wwwroot/js/admin-org-chart.js
@@ -39,8 +39,8 @@ window.AdminOrgChart = {
this.chart = new d3.OrgChart()
.container('#' + containerId)
.data(data)
- .nodeWidth((d) => 160)
- .nodeHeight((d) => 80)
+ .nodeWidth((d) => 178)
+ .nodeHeight((d) => 92)
.childrenMargin((d) => 60)
.compactMarginBetween((d) => 20)
.compactMarginPair((d) => 20)
@@ -83,12 +83,19 @@ window.AdminOrgChart = {
`;
}
- // Highlight badge for target week matches
- let highlightBadge = '';
- if (weekFilterActive && isTargetWeek) {
- highlightBadge = '✨
';
+ // نوع فعالسازی - inline pill در meta row
+ let activationTypePill = '';
+ if (data.isNewActivation === true) {
+ activationTypePill = 'عضو جدید';
+ } else if (data.isNewActivation === false) {
+ activationTypePill = 'تمدید';
}
+ // نام پکیج badge
+ const packageBadge = data.packageName
+ ? `${data.packageName}
`
+ : '';
+
// Avatar - first letter of name
const firstChar = data.userName ? data.userName.charAt(0).toUpperCase() : '?';
@@ -114,6 +121,14 @@ window.AdminOrgChart = {
if (data.activationWeekDefinitionId) {
tooltipLines.push(`📆 هفته: ${data.activationWeekDefinitionId}`);
}
+ if (data.packageName) {
+ tooltipLines.push(`📦 پکیج: ${data.packageName}`);
+ }
+ if (data.isNewActivation === true) {
+ tooltipLines.push('🆕 نوع: اولین فعالسازی');
+ } else if (data.isNewActivation === false) {
+ tooltipLines.push('🔄 نوع: خرید مجدد');
+ }
if (weekFilterActive) {
tooltipLines.push(isTargetWeek ? '🎯 فعال در هفته انتخابی' : '⚪ خارج از هفته انتخابی');
}
@@ -125,14 +140,15 @@ window.AdminOrgChart = {
data-user-id="${data.userId}"
title="${tooltipText}">
${weekIndicator}
- ${highlightBadge}