using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Security.Cryptography; using System.Text; using Haoliang.Models.User; using Haoliang.Data.Repositories; namespace Haoliang.Data.Repositories { public interface IUserRepository : IRepository { Task GetByUsernameAsync(string username); Task GetByEmailAsync(string email); Task UsernameExistsAsync(string username); Task EmailExistsAsync(string email); Task ValidatePasswordAsync(string username, string password); Task AuthenticateAsync(string username, string password); Task> GetByRoleIdAsync(int roleId); Task UpdateLastLoginAsync(int userId); Task ChangePasswordAsync(int userId, string oldPassword, string newPassword); Task ResetPasswordAsync(int userId, string newPassword); Task> GetActiveUsersAsync(); Task IsUserActiveAsync(string username); } public class UserRepository : Repository, IUserRepository { private readonly CNCDbContext _context; public UserRepository(CNCDbContext context) : base(context) { _context = context; } public async Task GetByUsernameAsync(string username) { return await _context.Users .Include(u => u.Role) .FirstOrDefaultAsync(u => u.Username == username); } public async Task GetByEmailAsync(string email) { return await _context.Users .Include(u => u.Role) .FirstOrDefaultAsync(u => u.Email == email); } public async Task UsernameExistsAsync(string username) { return await _context.Users .AnyAsync(u => u.Username == username); } public async Task EmailExistsAsync(string email) { return await _context.Users .AnyAsync(u => u.Email == email); } public async Task ValidatePasswordAsync(string username, string password) { var user = await GetByUsernameAsync(username); if (user == null || !user.IsActive) return false; return VerifyPassword(password, user.PasswordHash); } public async Task AuthenticateAsync(string username, string password) { var user = await GetByUsernameAsync(username); if (user == null || !user.IsActive) return null; if (VerifyPassword(password, user.PasswordHash)) { await UpdateLastLoginAsync(user.Id); return user; } return null; } public async Task> GetByRoleIdAsync(int roleId) { return await _context.Users .Include(u => u.Role) .Where(u => u.RoleId == roleId) .OrderBy(u => u.Username) .ToListAsync(); } public async Task UpdateLastLoginAsync(int userId) { var user = await GetByIdAsync(userId); if (user != null) { user.LastLoginTime = DateTime.Now; user.UpdatedAt = DateTime.Now; Update(user); await SaveAsync(); } } public async Task ChangePasswordAsync(int userId, string oldPassword, string newPassword) { var user = await GetByIdAsync(userId); if (user == null) return false; if (!VerifyPassword(oldPassword, user.PasswordHash)) return false; user.PasswordHash = HashPassword(newPassword); user.UpdatedAt = DateTime.Now; Update(user); await SaveAsync(); return true; } public async Task ResetPasswordAsync(int userId, string newPassword) { var user = await GetByIdAsync(userId); if (user == null) return false; user.PasswordHash = HashPassword(newPassword); user.UpdatedAt = DateTime.Now; Update(user); await SaveAsync(); return true; } public async Task> GetActiveUsersAsync() { return await _context.Users .Include(u => u.Role) .Where(u => u.IsActive) .OrderBy(u => u.Username) .ToListAsync(); } public async Task IsUserActiveAsync(string username) { var user = await GetByUsernameAsync(username); return user != null && user.IsActive; } private string HashPassword(string password) { using (var sha256 = SHA256.Create()) { var bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password)); return Convert.ToBase64String(bytes); } } private bool VerifyPassword(string password, string hash) { return HashPassword(password) == hash; } } public interface IRoleRepository : IRepository { Task GetByNameAsync(string roleName); Task RoleNameExistsAsync(string roleName); Task> GetRolePermissionsAsync(int roleId); Task AddPermissionToRoleAsync(int roleId, int permissionId); Task RemovePermissionFromRoleAsync(int roleId, int permissionId); Task UserHasPermissionAsync(int userId, string permissionName); } public class RoleRepository : Repository, IRoleRepository { private readonly CNCDbContext _context; public RoleRepository(CNCDbContext context) : base(context) { _context = context; } public async Task GetByNameAsync(string roleName) { return await _context.Roles .FirstOrDefaultAsync(r => r.RoleName == roleName); } public async Task RoleNameExistsAsync(string roleName) { return await _context.Roles .AnyAsync(r => r.RoleName == roleName); } public async Task> GetRolePermissionsAsync(int roleId) { var role = await GetByIdAsync(roleId); if (role == null) return new List(); var permissionIds = role.Permissions.Select(p => int.Parse(p.Split('_')[0])).ToList(); return await _context.Permissions .Where(p => permissionIds.Contains(p.Id)) .ToListAsync(); } public async Task AddPermissionToRoleAsync(int roleId, int permissionId) { var role = await GetByIdAsync(roleId); if (role == null) return false; if (!role.Permissions.Contains(permissionId.ToString())) { role.Permissions.Add(permissionId.ToString()); role.UpdatedAt = DateTime.Now; Update(role); await SaveAsync(); return true; } return false; } public async Task RemovePermissionFromRoleAsync(int roleId, int permissionId) { var role = await GetByIdAsync(roleId); if (role == null) return false; if (role.Permissions.Contains(permissionId.ToString())) { role.Permissions.Remove(permissionId.ToString()); role.UpdatedAt = DateTime.Now; Update(role); await SaveAsync(); return true; } return false; } public async Task UserHasPermissionAsync(int userId, string permissionName) { var user = await _context.Users .Include(u => u.Role) .FirstOrDefaultAsync(u => u.Id == userId); if (user == null || user.Role == null) return false; return user.Role.Permissions.Contains(permissionName); } } public interface IEmployeeRepository : IRepository { Task GetByEmployeeCodeAsync(string employeeCode); Task EmployeeCodeExistsAsync(string employeeCode); Task> GetByDepartmentAsync(string department); Task> GetByPositionAsync(string position); Task GetAssignedEmployeeAsync(int deviceId); Task AssignDeviceToEmployeeAsync(int employeeId, int deviceId); Task UnassignDeviceFromEmployeeAsync(int employeeId, int deviceId); } public class EmployeeRepository : Repository, IEmployeeRepository { private readonly CNCDbContext _context; public EmployeeRepository(CNCDbContext context) : base(context) { _context = context; } public async Task GetByEmployeeCodeAsync(string employeeCode) { return await _context.Employees .FirstOrDefaultAsync(e => e.EmployeeCode == employeeCode); } public async Task EmployeeCodeExistsAsync(string employeeCode) { return await _context.Employees .AnyAsync(e => e.EmployeeCode == employeeCode); } public async Task> GetByDepartmentAsync(string department) { return await _context.Employees .Where(e => e.Department == department) .OrderBy(e => e.Name) .ToListAsync(); } public async Task> GetByPositionAsync(string position) { return await _context.Employees .Where(e => e.Position == position) .OrderBy(e => e.Name) .ToListAsync(); } public async Task GetAssignedEmployeeAsync(int deviceId) { var assignment = await _context.DeviceAssignments .FirstOrDefaultAsync(da => da.DeviceId == deviceId && da.EndDate == null); if (assignment != null) { return await GetByIdAsync(assignment.EmployeeId); } return null; } public async Task AssignDeviceToEmployeeAsync(int employeeId, int deviceId) { var existingAssignment = await _context.DeviceAssignments .FirstOrDefaultAsync(da => da.DeviceId == deviceId && da.EndDate == null); if (existingAssignment != null) return false; var assignment = new DeviceAssignment { EmployeeId = employeeId, DeviceId = deviceId, AssignmentDate = DateTime.Now, CreatedAt = DateTime.Now }; await _context.DeviceAssignments.AddAsync(assignment); await SaveAsync(); return true; } public async Task UnassignDeviceFromEmployeeAsync(int employeeId, int deviceId) { var assignment = await _context.DeviceAssignments .FirstOrDefaultAsync(da => da.EmployeeId == employeeId && da.DeviceId == deviceId && da.EndDate == null); if (assignment != null) { assignment.EndDate = DateTime.Now; _context.DeviceAssignments.Update(assignment); await SaveAsync(); return true; } return false; } } }