413 lines
14 KiB
C#
413 lines
14 KiB
C#
using HoneyBox.Admin.Data;
|
||
using HoneyBox.Admin.Entities;
|
||
using HoneyBox.Admin.Models.AdminUser;
|
||
using HoneyBox.Admin.Models.Common;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace HoneyBox.Admin.Services;
|
||
|
||
/// <summary>
|
||
/// 管理员服务实现
|
||
/// </summary>
|
||
public class AdminUserService : IAdminUserService
|
||
{
|
||
private readonly AdminDbContext _dbContext;
|
||
private readonly ILogger<AdminUserService> _logger;
|
||
|
||
// 超级管理员角色编码
|
||
private const string SuperAdminRoleCode = "super_admin";
|
||
|
||
public AdminUserService(AdminDbContext dbContext, ILogger<AdminUserService> logger)
|
||
{
|
||
_dbContext = dbContext;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PagedResult<AdminUserDto>> GetListAsync(AdminUserQueryRequest request)
|
||
{
|
||
var query = _dbContext.AdminUsers
|
||
.Include(u => u.Department)
|
||
.Include(u => u.AdminUserRoles)
|
||
.ThenInclude(ur => ur.Role)
|
||
.AsQueryable();
|
||
|
||
// 用户名筛选
|
||
if (!string.IsNullOrWhiteSpace(request.Username))
|
||
{
|
||
query = query.Where(u => u.Username.Contains(request.Username));
|
||
}
|
||
|
||
// 真实姓名筛选
|
||
if (!string.IsNullOrWhiteSpace(request.RealName))
|
||
{
|
||
query = query.Where(u => u.RealName != null && u.RealName.Contains(request.RealName));
|
||
}
|
||
|
||
// 手机号筛选
|
||
if (!string.IsNullOrWhiteSpace(request.Phone))
|
||
{
|
||
query = query.Where(u => u.Phone != null && u.Phone.Contains(request.Phone));
|
||
}
|
||
|
||
// 部门筛选
|
||
if (request.DepartmentId.HasValue)
|
||
{
|
||
query = query.Where(u => u.DepartmentId == request.DepartmentId.Value);
|
||
}
|
||
|
||
// 状态筛选
|
||
if (request.Status.HasValue)
|
||
{
|
||
query = query.Where(u => u.Status == request.Status.Value);
|
||
}
|
||
|
||
var total = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.OrderByDescending(u => u.CreatedAt)
|
||
.Skip((request.Page - 1) * request.PageSize)
|
||
.Take(request.PageSize)
|
||
.Select(u => new AdminUserDto
|
||
{
|
||
Id = u.Id,
|
||
Username = u.Username,
|
||
RealName = u.RealName,
|
||
Avatar = u.Avatar,
|
||
Email = u.Email,
|
||
Phone = u.Phone,
|
||
DepartmentId = u.DepartmentId,
|
||
DepartmentName = u.Department != null ? u.Department.Name : null,
|
||
Status = u.Status,
|
||
LastLoginTime = u.LastLoginTime,
|
||
LastLoginIp = u.LastLoginIp,
|
||
CreatedAt = u.CreatedAt,
|
||
UpdatedAt = u.UpdatedAt,
|
||
Remark = u.Remark,
|
||
RoleIds = u.AdminUserRoles.Select(ur => ur.RoleId).ToList(),
|
||
RoleNames = u.AdminUserRoles.Select(ur => ur.Role.Name).ToList()
|
||
})
|
||
.ToListAsync();
|
||
|
||
return new PagedResult<AdminUserDto>
|
||
{
|
||
List = list,
|
||
Total = total,
|
||
Page = request.Page,
|
||
PageSize = request.PageSize
|
||
};
|
||
}
|
||
|
||
|
||
/// <inheritdoc />
|
||
public async Task<AdminUserDto> GetByIdAsync(long id)
|
||
{
|
||
var user = await _dbContext.AdminUsers
|
||
.Include(u => u.Department)
|
||
.Include(u => u.AdminUserRoles)
|
||
.ThenInclude(ur => ur.Role)
|
||
.Include(u => u.AdminUserMenus)
|
||
.FirstOrDefaultAsync(u => u.Id == id);
|
||
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
return new AdminUserDto
|
||
{
|
||
Id = user.Id,
|
||
Username = user.Username,
|
||
RealName = user.RealName,
|
||
Avatar = user.Avatar,
|
||
Email = user.Email,
|
||
Phone = user.Phone,
|
||
DepartmentId = user.DepartmentId,
|
||
DepartmentName = user.Department?.Name,
|
||
Status = user.Status,
|
||
LastLoginTime = user.LastLoginTime,
|
||
LastLoginIp = user.LastLoginIp,
|
||
CreatedAt = user.CreatedAt,
|
||
UpdatedAt = user.UpdatedAt,
|
||
Remark = user.Remark,
|
||
RoleIds = user.AdminUserRoles.Select(ur => ur.RoleId).ToList(),
|
||
RoleNames = user.AdminUserRoles.Select(ur => ur.Role.Name).ToList(),
|
||
MenuIds = user.AdminUserMenus.Select(um => um.MenuId).ToList()
|
||
};
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<long> CreateAsync(CreateAdminUserRequest request, long? createdBy = null)
|
||
{
|
||
// 检查用户名是否重复
|
||
var usernameExists = await _dbContext.AdminUsers.AnyAsync(u => u.Username == request.Username);
|
||
if (usernameExists)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.DuplicateUsername, "用户名已存在");
|
||
}
|
||
|
||
// 验证部门是否存在
|
||
if (request.DepartmentId.HasValue)
|
||
{
|
||
var departmentExists = await _dbContext.Departments.AnyAsync(d => d.Id == request.DepartmentId.Value);
|
||
if (!departmentExists)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
|
||
}
|
||
}
|
||
|
||
var user = new Entities.AdminUser
|
||
{
|
||
Username = request.Username,
|
||
PasswordHash = AuthService.HashPassword(request.Password),
|
||
RealName = request.RealName,
|
||
Avatar = request.Avatar,
|
||
Email = request.Email,
|
||
Phone = request.Phone,
|
||
DepartmentId = request.DepartmentId,
|
||
Status = request.Status,
|
||
Remark = request.Remark,
|
||
CreatedBy = createdBy,
|
||
CreatedAt = DateTime.Now
|
||
};
|
||
|
||
_dbContext.AdminUsers.Add(user);
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
// 分配角色
|
||
if (request.RoleIds.Any())
|
||
{
|
||
var userRoles = request.RoleIds.Distinct().Select(roleId => new AdminUserRole
|
||
{
|
||
AdminUserId = user.Id,
|
||
RoleId = roleId
|
||
});
|
||
_dbContext.AdminUserRoles.AddRange(userRoles);
|
||
await _dbContext.SaveChangesAsync();
|
||
}
|
||
|
||
_logger.LogInformation("创建管理员成功: {UserId} - {Username}", user.Id, user.Username);
|
||
return user.Id;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task UpdateAsync(long id, UpdateAdminUserRequest request)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(id);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
// 验证部门是否存在
|
||
if (request.DepartmentId.HasValue)
|
||
{
|
||
var departmentExists = await _dbContext.Departments.AnyAsync(d => d.Id == request.DepartmentId.Value);
|
||
if (!departmentExists)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
|
||
}
|
||
}
|
||
|
||
user.RealName = request.RealName;
|
||
user.Avatar = request.Avatar;
|
||
user.Email = request.Email;
|
||
user.Phone = request.Phone;
|
||
user.DepartmentId = request.DepartmentId;
|
||
user.Status = request.Status;
|
||
user.Remark = request.Remark;
|
||
user.UpdatedAt = DateTime.Now;
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
_logger.LogInformation("更新管理员成功: {UserId} - {Username}", user.Id, user.Username);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task DeleteAsync(long id)
|
||
{
|
||
var user = await _dbContext.AdminUsers
|
||
.Include(u => u.AdminUserRoles)
|
||
.ThenInclude(ur => ur.Role)
|
||
.FirstOrDefaultAsync(u => u.Id == id);
|
||
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
// 检查是否是最后一个超级管理员
|
||
var isSuperAdmin = user.AdminUserRoles.Any(ur => ur.Role.Code == SuperAdminRoleCode);
|
||
if (isSuperAdmin)
|
||
{
|
||
var superAdminCount = await _dbContext.AdminUserRoles
|
||
.Include(ur => ur.Role)
|
||
.Where(ur => ur.Role.Code == SuperAdminRoleCode)
|
||
.Select(ur => ur.AdminUserId)
|
||
.Distinct()
|
||
.CountAsync();
|
||
|
||
if (superAdminCount <= 1)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.CannotDeleteLastSuperAdmin, "不能删除最后一个超级管理员");
|
||
}
|
||
}
|
||
|
||
// 删除关联数据
|
||
var userRoles = await _dbContext.AdminUserRoles.Where(ur => ur.AdminUserId == id).ToListAsync();
|
||
_dbContext.AdminUserRoles.RemoveRange(userRoles);
|
||
|
||
var userMenus = await _dbContext.AdminUserMenus.Where(um => um.AdminUserId == id).ToListAsync();
|
||
_dbContext.AdminUserMenus.RemoveRange(userMenus);
|
||
|
||
_dbContext.AdminUsers.Remove(user);
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("删除管理员成功: {UserId} - {Username}", id, user.Username);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<long>> GetRoleIdsAsync(long userId)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
return await _dbContext.AdminUserRoles
|
||
.Where(ur => ur.AdminUserId == userId)
|
||
.Select(ur => ur.RoleId)
|
||
.ToListAsync();
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task AssignRolesAsync(long userId, List<long> roleIds)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
// 删除现有关联
|
||
var existingRoles = await _dbContext.AdminUserRoles.Where(ur => ur.AdminUserId == userId).ToListAsync();
|
||
_dbContext.AdminUserRoles.RemoveRange(existingRoles);
|
||
|
||
// 添加新关联
|
||
if (roleIds.Any())
|
||
{
|
||
var newRoles = roleIds.Distinct().Select(roleId => new AdminUserRole
|
||
{
|
||
AdminUserId = userId,
|
||
RoleId = roleId
|
||
});
|
||
_dbContext.AdminUserRoles.AddRange(newRoles);
|
||
}
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
_logger.LogInformation("管理员 {UserId} 分配角色成功,角色数量: {Count}", userId, roleIds.Count);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<long>> GetMenuIdsAsync(long userId)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
return await _dbContext.AdminUserMenus
|
||
.Where(um => um.AdminUserId == userId)
|
||
.Select(um => um.MenuId)
|
||
.ToListAsync();
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task AssignMenusAsync(long userId, List<long> menuIds)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
// 删除现有关联
|
||
var existingMenus = await _dbContext.AdminUserMenus.Where(um => um.AdminUserId == userId).ToListAsync();
|
||
_dbContext.AdminUserMenus.RemoveRange(existingMenus);
|
||
|
||
// 添加新关联
|
||
if (menuIds.Any())
|
||
{
|
||
var newMenus = menuIds.Distinct().Select(menuId => new AdminUserMenu
|
||
{
|
||
AdminUserId = userId,
|
||
MenuId = menuId
|
||
});
|
||
_dbContext.AdminUserMenus.AddRange(newMenus);
|
||
}
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
_logger.LogInformation("管理员 {UserId} 分配用户专属菜单成功,菜单数量: {Count}", userId, menuIds.Count);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task AssignDepartmentAsync(long userId, long? departmentId)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
// 验证部门是否存在
|
||
if (departmentId.HasValue)
|
||
{
|
||
var departmentExists = await _dbContext.Departments.AnyAsync(d => d.Id == departmentId.Value);
|
||
if (!departmentExists)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
|
||
}
|
||
}
|
||
|
||
user.DepartmentId = departmentId;
|
||
user.UpdatedAt = DateTime.Now;
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("管理员 {UserId} 分配部门成功,部门ID: {DepartmentId}", userId, departmentId);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task SetStatusAsync(long userId, bool enabled)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
user.Status = enabled ? (byte)1 : (byte)0;
|
||
user.UpdatedAt = DateTime.Now;
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("管理员 {UserId} 状态设置为: {Status}", userId, enabled ? "启用" : "禁用");
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task ResetPasswordAsync(long userId, string newPassword)
|
||
{
|
||
var user = await _dbContext.AdminUsers.FindAsync(userId);
|
||
if (user == null)
|
||
{
|
||
throw new AdminException(AdminErrorCodes.InvalidParameter, "管理员不存在");
|
||
}
|
||
|
||
user.PasswordHash = AuthService.HashPassword(newPassword);
|
||
user.UpdatedAt = DateTime.Now;
|
||
await _dbContext.SaveChangesAsync();
|
||
|
||
_logger.LogInformation("管理员 {UserId} 密码重置成功", userId);
|
||
}
|
||
}
|