LSFE/LSFE.Domain/Services/Account/NavigationService.cs
2026-07-30 10:31:04 +08:00

170 lines
6.9 KiB
C#

using LSFE.Domain.Contracts;
using LSFE.Infrastructure.Database;
using LSFE.Infrastructure.Dto.Account;
using LSFE.Infrastructure.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System.Data;
namespace LSFE.Domain.Services.Account
{
public class NavigationService : INavigationService
{
private readonly LSFEDbContext _context;
private readonly UserManager<AppsUsers> _userManager;
public NavigationService(LSFEDbContext context, UserManager<AppsUsers> userManager)
{
_context = context;
_userManager = userManager;
}
public async Task<NavigationResponseDto> GetUserNavigationAsync(string userId)
{
try
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return new NavigationResponseDto
{
Success = false,
Message = "User not found or inactive",
Data = new List<NavigationItemDto>()
};
}
// Get user roles using UserManager
var roles = await _userManager.GetRolesAsync(user);
if (!roles.Any())
{
return new NavigationResponseDto
{
Success = false,
Message = "User has no assigned roles",
Data = new List<NavigationItemDto>()
};
}
// Get role IDs from role names
var roleIds = await _context.Roles
.Where(r => roles.Contains(r.Name))
.Select(r => r.Id)
.ToListAsync();
// Get navigation for all user roles
var navigationItems = await GetNavigationByRoleIdsAsync(roleIds);
return new NavigationResponseDto
{
Success = true,
Data = navigationItems,
Message = "Navigation retrieved successfully"
};
}
catch (Exception ex)
{
return new NavigationResponseDto
{
Success = false,
Message = $"Error retrieving navigation: {ex.Message}",
Data = new List<NavigationItemDto>()
};
}
}
public async Task<List<NavigationItemDto>> GetNavigationByRoleIdsAsync(List<string> roleIds)
{
try
{
var roleIdsParam = string.Join(",", roleIds);
using (var command = _context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "GetUserNavigation";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@RoleIds", roleIdsParam));
await _context.Database.OpenConnectionAsync();
using (var result = await command.ExecuteReaderAsync())
{
var rootModules = new List<NavigationItemDto>();
var childModules = new List<NavigationItemDto>();
// Read root modules
while (await result.ReadAsync())
{
rootModules.Add(new NavigationItemDto
{
Id = result["Id"].ToString(),
Label = result["Label"].ToString(),
Icon = result["Icon"].ToString(),
Route = result["Route"].ToString(),
Badge = result["Badge"]?.ToString(),
Permissions = new PermissionsDto
{
CanView = Convert.ToBoolean(result["CanView"]),
CanCreate = Convert.ToBoolean(result["CanCreate"]),
CanEdit = Convert.ToBoolean(result["CanEdit"]),
CanDelete = Convert.ToBoolean(result["CanDelete"])
},
Children = new List<NavigationItemDto>()
});
}
// Read child modules
if (await result.NextResultAsync())
{
while (await result.ReadAsync())
{
childModules.Add(new NavigationItemDto
{
Id = result["Id"].ToString(),
Label = result["Label"].ToString(),
Icon = result["Icon"].ToString(),
Route = result["Route"].ToString(),
ParentModuleId = result["ParentModuleId"] != DBNull.Value
? Convert.ToInt32(result["ParentModuleId"])
: (int?)null,
Permissions = new PermissionsDto
{
CanView = Convert.ToBoolean(result["CanView"]),
CanCreate = Convert.ToBoolean(result["CanCreate"]),
CanEdit = Convert.ToBoolean(result["CanEdit"]),
CanDelete = Convert.ToBoolean(result["CanDelete"])
}
});
}
}
// Attach children to parents
foreach (var parent in rootModules)
{
var children = childModules
.Where(c => c.ParentModuleId.ToString() == parent.Id)
.ToList();
parent.Children = children.Any() ? children : null;
}
return rootModules;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error in GetNavigationByRoleIdsAsync: {ex.Message}");
throw;
}
}
// Optional: Add method to get single role navigation (for backwards compatibility)
public async Task<List<NavigationItemDto>> GetNavigationByRoleAsync(string roleId)
{
return await GetNavigationByRoleIdsAsync(new List<string> { roleId });
}
}
}