feat: integrate d3-org-chart for network visualization and add SignalR token notification service
This commit is contained in:
@@ -41,6 +41,39 @@ public class NetworkMembershipService
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get subordinate's network tree (with security check on backend)
|
||||
/// Maps to: NetworkMembershipCQ.GetSubordinateTree
|
||||
/// </summary>
|
||||
public async Task<NetworkTreeDto> GetSubordinateTreeAsync(long targetUserId, int maxDepth = 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new GetSubordinateTreeRequest
|
||||
{
|
||||
TargetUserId = targetUserId,
|
||||
MaxDepth = maxDepth
|
||||
};
|
||||
var response = await _client.GetSubordinateTreeAsync(request);
|
||||
|
||||
return new NetworkTreeDto
|
||||
{
|
||||
RootNode = MapNodeFromProto(response.RootNode),
|
||||
TotalMembers = response.TotalMembers,
|
||||
CurrentDepth = response.CurrentDepth
|
||||
};
|
||||
}
|
||||
catch (Grpc.Core.RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.PermissionDenied)
|
||||
{
|
||||
throw new UnauthorizedAccessException("شما اجازه مشاهده درخت این کاربر را ندارید");
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Fallback to current user's tree
|
||||
return await GetMyNetworkTreeAsync(maxDepth);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get current user's network statistics
|
||||
/// Maps to: NetworkMembershipCQ.GetMyNetworkStatistics
|
||||
@@ -102,6 +135,10 @@ public class NetworkMembershipService
|
||||
Avatar = node.Avatar,
|
||||
Position = node.Position,
|
||||
Level = node.Level,
|
||||
IsActive = node.HasChildren, // Temporary: use HasChildren as active indicator until proto is updated
|
||||
IsClubActive = false, // Will be populated when proto is updated
|
||||
ActivationWeekNumber = null, // Will be populated when proto is updated
|
||||
JoinedAt = null, // Will be populated when proto is updated
|
||||
LeftChild = MapNodeFromProto(node.LeftChild),
|
||||
RightChild = MapNodeFromProto(node.RightChild)
|
||||
};
|
||||
@@ -111,8 +148,8 @@ public class NetworkMembershipService
|
||||
{
|
||||
return new NetworkTreeDto
|
||||
{
|
||||
CurrentDepth = 2,
|
||||
TotalMembers = 5,
|
||||
CurrentDepth = 3,
|
||||
TotalMembers = 7,
|
||||
RootNode = new NetworkNodeDto
|
||||
{
|
||||
UserId = 1,
|
||||
@@ -120,13 +157,38 @@ public class NetworkMembershipService
|
||||
Mobile = "09121234567",
|
||||
Position = "Root",
|
||||
Level = 0,
|
||||
IsActive = true,
|
||||
IsClubActive = true,
|
||||
LeftChild = new NetworkNodeDto
|
||||
{
|
||||
UserId = 2,
|
||||
FullName = "علی محمدی",
|
||||
Mobile = "09121234568",
|
||||
Position = "Left",
|
||||
Level = 1
|
||||
Level = 1,
|
||||
IsActive = true,
|
||||
IsClubActive = true,
|
||||
JoinedAt = DateTime.Now.AddDays(-30),
|
||||
LeftChild = new NetworkNodeDto
|
||||
{
|
||||
UserId = 4,
|
||||
FullName = "رضا کریمی",
|
||||
Mobile = "09121234570",
|
||||
Position = "Left",
|
||||
Level = 2,
|
||||
IsActive = true,
|
||||
JoinedAt = DateTime.Now.AddDays(-15)
|
||||
},
|
||||
RightChild = new NetworkNodeDto
|
||||
{
|
||||
UserId = 5,
|
||||
FullName = "زهرا احمدی",
|
||||
Mobile = "09121234571",
|
||||
Position = "Right",
|
||||
Level = 2,
|
||||
IsActive = false,
|
||||
JoinedAt = DateTime.Now.AddDays(-10)
|
||||
}
|
||||
},
|
||||
RightChild = new NetworkNodeDto
|
||||
{
|
||||
@@ -134,7 +196,20 @@ public class NetworkMembershipService
|
||||
FullName = "فاطمه حسینی",
|
||||
Mobile = "09121234569",
|
||||
Position = "Right",
|
||||
Level = 1
|
||||
Level = 1,
|
||||
IsActive = true,
|
||||
JoinedAt = DateTime.Now.AddDays(-25),
|
||||
LeftChild = new NetworkNodeDto
|
||||
{
|
||||
UserId = 6,
|
||||
FullName = "محمد نوری",
|
||||
Mobile = "09121234572",
|
||||
Position = "Left",
|
||||
Level = 2,
|
||||
IsActive = true,
|
||||
IsClubActive = true,
|
||||
JoinedAt = DateTime.Now.AddDays(-5)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user