feat: Add club status and activation week filters to network tree
Build and Deploy / build (push) Successful in 2m33s

This commit is contained in:
masoodafar-web
2025-12-14 04:16:13 +03:30
parent cc721da65f
commit d1940033db
4 changed files with 138 additions and 23 deletions
+2 -2
View File
@@ -134,9 +134,9 @@
<PackageReference Include="Foursat.BackOffice.BFF.Health.Protobuf" Version="1.0.4" />
<PackageReference Include="Foursat.BackOffice.BFF.ManualPayment.Protobuf" Version="0.0.3" />
<PackageReference Include="Foursat.BackOffice.BFF.ManualPayment.Protobuf" Version="0.0.4" />
<PackageReference Include="Foursat.BackOffice.BFF.NetworkMembership.Protobuf" Version="0.0.7" />
<PackageReference Include="Foursat.BackOffice.BFF.NetworkMembership.Protobuf" Version="0.0.9" />
<PackageReference Include="Foursat.BackOffice.BFF.Otp.Protobuf" Version="0.0.112" />
@@ -74,14 +74,14 @@
<PropertyColumn Property="x => x.ValuePerBalance" Title="ارزش هر بالانس">
<CellTemplate>
@context.Item.ValuePerBalance.ToString("N0") ریال
@context.Item.ValuePerBalance.ToString("N0")
</CellTemplate>
</PropertyColumn>
<PropertyColumn Property="x => x.TotalAmount" Title="مبلغ کل">
<CellTemplate>
<MudText Typo="Typo.body2" Color="Color.Primary">
<strong>@context.Item.TotalAmount.ToString("N0") ریال</strong>
<strong>@context.Item.TotalAmount.ToString("N0") </strong>
</MudText>
</CellTemplate>
</PropertyColumn>
@@ -9,7 +9,7 @@
<MudText Typo="Typo.h4" Class="mb-4">درخت شبکه</MudText>
<MudPaper Class="pa-4 mb-4">
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Center">
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Center" Class="mb-3">
<div style="max-width: 300px; min-width: 250px;">
<UserAutoComplete Label="جستجوی کاربر"
@bind-SelectedUserId="_searchUserId" />
@@ -21,6 +21,21 @@
Disabled="_isLoading">
نمایش درخت
</MudButton>
</MudStack>
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Center">
<div style="max-width: 200px; min-width: 150px;">
<MudSelect T="bool?" Label="وضعیت باشگاه" @bind-Value="_clubActiveFilter" Variant="Variant.Outlined" Clearable="true">
<MudSelectItem T="bool?" Value="@(null)">همه</MudSelectItem>
<MudSelectItem T="bool?" Value="@(true)">فعال</MudSelectItem>
<MudSelectItem T="bool?" Value="@(false)">غیرفعال</MudSelectItem>
</MudSelect>
</div>
<div style="max-width: 200px; min-width: 150px;">
<WeekNumberPicker Label="هفته فعالسازی"
@bind-SelectedWeekNumber="_activationWeekFilter" />
</div>
<MudSpacer />
<MudStack Row="true" Spacing="2">
<MudChip T="string" Color="Color.Info" Size="Size.Small">
@@ -67,17 +82,13 @@
<PropertyColumn Property="x => x.NetworkLevel" Title="سطح" />
<PropertyColumn Property="x => x.IsActive" Title="وضعیت">
<PropertyColumn Property="x => x.IsClubActive" Title="وضعیت">
<CellTemplate>
@if (context.Item.IsActive!=null)
{
<MudChip T="string"
Color="@((bool)context.Item.IsActive ? Color.Success : Color.Error)"
Color="@(context.Item.IsClubActive ? Color.Success : Color.Error)"
Size="Size.Small">
@((bool)context.Item.IsActive ? "فعال" : "غیرفعال")
@(context.Item.IsClubActive ? "فعال" : "غیرفعال")
</MudChip>
}
</CellTemplate>
</PropertyColumn>
@@ -94,6 +105,45 @@
</CellTemplate>
</PropertyColumn>
<PropertyColumn Property="x => x.IsClubActive" Title="باشگاه">
<CellTemplate>
@if (context.Item.IsClubActive)
{
<MudChip T="string" Color="Color.Success" Size="Size.Small">فعال</MudChip>
}
else
{
<MudChip T="string" Color="Color.Default" Size="Size.Small">غیرفعال</MudChip>
}
</CellTemplate>
</PropertyColumn>
<PropertyColumn Property="x => x.ActivationWeekNumber" Title="هفته فعالسازی">
<CellTemplate>
@if (!string.IsNullOrEmpty(context.Item.ActivationWeekNumber))
{
<MudText Typo="Typo.body2">@context.Item.ActivationWeekNumber</MudText>
}
else
{
<MudText Typo="Typo.body2" Color="Color.Default">-</MudText>
}
</CellTemplate>
</PropertyColumn>
<PropertyColumn Property="x => x.ClubActivatedAt" Title="تاریخ فعالسازی باشگاه">
<CellTemplate>
@if (context.Item.ClubActivatedAt != null)
{
@context.Item.ClubActivatedAt.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd")
}
else
{
<MudText Typo="Typo.body2" Color="Color.Default">-</MudText>
}
</CellTemplate>
</PropertyColumn>
<TemplateColumn Title="عملیات" Sortable="false">
<CellTemplate>
<MudButton Size="Size.Small"
@@ -129,6 +179,8 @@
private int _leftCount;
private int _rightCount;
private DotNetObjectReference<NetworkTreeViewer> _dotNetRef;
private bool? _clubActiveFilter;
private string? _activationWeekFilter;
protected override void OnInitialized()
{
@@ -156,7 +208,13 @@
try
{
var request = new GetNetworkTreeRequest { UserId = _searchUserId.Value, MaxDepth = 20 };
var request = new GetNetworkTreeRequest
{
UserId = _searchUserId.Value,
MaxDepth = 20,
IsClubActive = _clubActiveFilter.HasValue ? _clubActiveFilter.Value : null,
ActivationWeekNumber = !string.IsNullOrEmpty(_activationWeekFilter) ? _activationWeekFilter : null
};
_treeData = await NetworkContract.GetNetworkTreeAsync(request);
CalculateStats();
@@ -187,7 +245,12 @@
parentId = n.ParentId,
networkLevel = n.NetworkLevel,
networkLeg = n.NetworkLeg,
isActive = n.IsActive ?? false
isActive = n.IsClubActive,
isClubActive = n.IsClubActive,
isActivatedInTargetWeek = n.IsActivatedInTargetWeek,
activationWeekNumber = _activationWeekFilter ?? "", // فیلتر UI
clubActivatedAt = n.ClubActivatedAt?.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd") ?? "",
userCreated = n.UserCreated?.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd") ?? ""
}).ToArray();
await JS.InvokeVoidAsync("NetworkTreeViewer.initialize", "network-tree-container", jsNodes);
+61 -9
View File
@@ -102,7 +102,14 @@ window.NetworkTreeViewer = {
// Add circles for nodes
node.append('circle')
.attr('r', 8)
.style('fill', d => d.data.isActive ? '#4caf50' : '#f44336')
.style('fill', d => {
// اگر هفته‌ای انتخاب نشده، همه سبز
if (!d.data.activationWeekNumber || d.data.activationWeekNumber === '') {
return '#4caf50';
}
// اگر در هفته هدف فعال شده، سبز، وگرنه قرمز
return d.data.isActivatedInTargetWeek ? '#4caf50' : '#f44336';
})
.style('stroke', '#fff')
.style('stroke-width', 2)
.style('cursor', 'pointer')
@@ -118,7 +125,7 @@ window.NetworkTreeViewer = {
.attr('text-anchor', 'middle')
.style('font-size', '12px')
.style('font-weight', 'bold')
.style('fill', '#333')
.style('fill', d => d.data.isClubActive ? '#424242' : '#9e9e9e')
.text(d => d.data.userName || `User ${d.data.userId}`);
// Add level info
@@ -137,33 +144,73 @@ window.NetworkTreeViewer = {
.style('fill', d => d.data.networkLeg === 0 ? '#4caf50' : '#ff9800')
.text(d => d.data.networkLeg === 0 ? 'چپ' : 'راست');
// Enhanced tooltip with club info
node.append('title')
.text(d => {
let tooltip = `نام: ${d.data.userName || 'User ' + d.data.userId}\nسطح: ${d.data.level}\nپایه: ${d.data.networkLeg === 0 ? 'چپ' : 'راست'}`;
if (d.data.userCreated) {
tooltip += `\nتاریخ ثبت‌نام: ${d.data.userCreated}`;
}
tooltip += `\nوضعیت باشگاه: ${d.data.isClubActive ? 'فعال' : 'غیرفعال'}`;
if (d.data.clubActivatedAt) {
tooltip += `\nتاریخ فعالسازی باشگاه: ${d.data.clubActivatedAt}`;
}
if (d.data.activationWeekNumber) {
tooltip += `\nهفته فعالسازی: ${d.data.activationWeekNumber}`;
}
return tooltip;
});
// Add legend
const legend = svg.append('g')
.attr('transform', `translate(${width - 150}, 20)`);
.attr('transform', `translate(${width - 180}, 20)`);
// Legend for title colors (club status)
legend.append('text')
.attr('x', 0)
.attr('y', 0)
.style('font-size', '12px')
.style('font-weight', 'bold')
.style('fill', '#424242')
.text('باشگاه فعال');
legend.append('text')
.attr('x', 0)
.attr('y', 20)
.style('font-size', '12px')
.style('font-weight', 'bold')
.style('fill', '#9e9e9e')
.text('باشگاه غیرفعال');
// Legend for circles (week status)
legend.append('circle')
.attr('cx', 0)
.attr('cy', 0)
.attr('cy', 50)
.attr('r', 6)
.style('fill', '#4caf50');
legend.append('text')
.attr('x', 12)
.attr('y', 4)
.attr('y', 54)
.style('font-size', '12px')
.text('فعال');
.text('فعال در هفته هدف');
legend.append('circle')
.attr('cx', 0)
.attr('cy', 25)
.attr('cy', 75)
.attr('r', 6)
.style('fill', '#f44336');
legend.append('text')
.attr('x', 12)
.attr('y', 29)
.attr('y', 79)
.style('font-size', '12px')
.text('غیرفعال');
.text('خارج از هفته هدف');
},
buildHierarchy: function(nodes) {
@@ -181,6 +228,11 @@ window.NetworkTreeViewer = {
level: node.networkLevel,
networkLeg: node.networkLeg,
isActive: node.isActive,
isClubActive: node.isClubActive,
isActivatedInTargetWeek: node.isActivatedInTargetWeek,
activationWeekNumber: node.activationWeekNumber,
clubActivatedAt: node.clubActivatedAt,
userCreated: node.userCreated,
children: []
});
});