34c5c508e0
- Updated the version of the Foursat.CMSMicroservice.Protobuf package from 0.0.197 to 0.0.199. - Added a new property `PackageName` to `NetworkNodeDto` and `FlatNetworkNodeDto` for better representation of membership packages. - Updated mapping in `NetworkMembershipService` to include the new `PackageName` property. - Enhanced the org chart display by adding a badge for the package name in the UI. These changes improve the clarity and functionality of the network membership features.
150 lines
4.9 KiB
C#
150 lines
4.9 KiB
C#
using CMSMicroservice.Protobuf.Protos.NetworkMembership;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
namespace FrontOffice.Main.Utilities;
|
|
|
|
/// <summary>
|
|
/// Service for Network Membership operations
|
|
/// Connected to FrontOffice.BFF gRPC NetworkMembershipCQ
|
|
/// </summary>
|
|
public class NetworkMembershipService
|
|
{
|
|
private readonly NetworkMembershipContract.NetworkMembershipContractClient _client;
|
|
|
|
public NetworkMembershipService(NetworkMembershipContract.NetworkMembershipContractClient client)
|
|
{
|
|
_client = client;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current user's network tree
|
|
/// Maps to: NetworkMembershipCQ.GetMyNetworkTree
|
|
/// </summary>
|
|
public async Task<NetworkTreeDto> GetMyNetworkTreeAsync(int maxDepth = 3)
|
|
{
|
|
try
|
|
{
|
|
var request = new GetMyNetworkTreeRequest { MaxDepth = maxDepth };
|
|
var response = await _client.GetMyNetworkTreeAsync(request);
|
|
|
|
return new NetworkTreeDto
|
|
{
|
|
RootNode = MapNodeFromProto(response.RootNode),
|
|
TotalMembers = response.TotalMembers,
|
|
CurrentDepth = response.CurrentDepth
|
|
};
|
|
}
|
|
catch
|
|
{
|
|
// Return empty tree if backend is unavailable
|
|
return new NetworkTreeDto
|
|
{
|
|
CurrentDepth = 0,
|
|
TotalMembers = 0,
|
|
RootNode = null
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <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
|
|
/// </summary>
|
|
public async Task<NetworkStatisticsDto> GetMyNetworkStatisticsAsync()
|
|
{
|
|
try
|
|
{
|
|
var response = await _client.GetMyNetworkStatisticsAsync(new Empty());
|
|
|
|
return new NetworkStatisticsDto
|
|
{
|
|
LeftLegCount = response.LeftLegCount,
|
|
RightLegCount = response.RightLegCount,
|
|
TotalMembers = response.TotalMembers,
|
|
TreeDepth = response.MaxDepth,
|
|
WeakerLeg = response.WeakerLeg,
|
|
LastMember = response.LastMember != null ? new LastMemberDto
|
|
{
|
|
UserId = response.LastMember.UserId,
|
|
FullName = response.LastMember.FullName,
|
|
Position = response.LastMember.Position,
|
|
JoinedAt = DateTime.Now // TODO: Add JoinedAt to proto
|
|
} : null
|
|
};
|
|
}
|
|
catch
|
|
{
|
|
// Return empty statistics if backend is unavailable
|
|
return new NetworkStatisticsDto
|
|
{
|
|
LeftLegCount = 0,
|
|
RightLegCount = 0,
|
|
TotalMembers = 0,
|
|
TreeDepth = 0,
|
|
WeakerLeg = string.Empty,
|
|
LastMember = null
|
|
};
|
|
}
|
|
}
|
|
|
|
#region Helper Methods
|
|
|
|
private static NetworkNodeDto? MapNodeFromProto(NetworkTreeNodeModel? node)
|
|
{
|
|
if (node == null) return null;
|
|
|
|
return new NetworkNodeDto
|
|
{
|
|
UserId = node.UserId,
|
|
FullName = node.FullName,
|
|
Mobile = node.Mobile,
|
|
Avatar = node.Avatar,
|
|
Position = node.Position,
|
|
Level = node.Level,
|
|
IsActive = node.IsActive,
|
|
IsClubActive = node.IsClubActive,
|
|
ReferralCode = node.ReferralCode,
|
|
PackageName = string.IsNullOrWhiteSpace(node.PackageName) ? null : node.PackageName,
|
|
ActivationWeekNumber = node.ActivationWeekDefinitionId?.ToString(),
|
|
JoinedAt = node.JoinedAt?.ToDateTime(),
|
|
LeftChild = MapNodeFromProto(node.LeftChild),
|
|
RightChild = MapNodeFromProto(node.RightChild)
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
}
|