using YD_Event.Application.Auth;
using YD_Event.Application.Menu;
using YD_Event.Application.User.Dtos;
using YD_Event.Core.Shared;
namespace YD_Event.Application.User;
///
/// 系统用户管理
///
public class SysUserService : BaseService, ITransient
{
private readonly ISqlSugarRepository _repository;
private readonly ISqlSugarRepository _userRoleRepository;
private readonly ISqlSugarRepository _roleRepository;
private readonly ISqlSugarRepository _orgRepository;
private readonly SysMenuService _sysMenuService;
private readonly AuthManager _authManager;
private readonly IEasyCachingProvider _easyCachingProvider;
private readonly IIdGenerator _idGenerator;
public SysUserService(ISqlSugarRepository repository,
ISqlSugarRepository userRoleRepository,
ISqlSugarRepository roleRepository,
ISqlSugarRepository orgRepository,
SysMenuService sysMenuService,
AuthManager authManager,
IEasyCachingProvider easyCachingProvider,
IIdGenerator idGenerator) : base(repository)
{
_repository = repository;
_userRoleRepository = userRoleRepository;
_roleRepository = roleRepository;
_orgRepository = orgRepository;
_sysMenuService = sysMenuService;
_authManager = authManager;
_easyCachingProvider = easyCachingProvider;
_idGenerator = idGenerator;
}
///
/// 系统用户分页查询
///
///
///
[DisplayName("系统用户分页查询")]
[HttpGet("page")]
public async Task> Page([FromQuery] QuerySysUserInput dto)
{
// 构造基本查询
var query = _repository.AsQueryable()
.Where(x => x.Id > 1) // 排除超级管理员或特定ID
.WhereIF(!string.IsNullOrWhiteSpace(dto.Name), x => x.Name.Contains(dto.Name))
.WhereIF(!string.IsNullOrWhiteSpace(dto.Account), x => x.Account.Contains(dto.Account))
.WhereIF(dto.StartTime.HasValue, x => x.CreatedTime >= dto.StartTime.Value)
.WhereIF(dto.EndTime.HasValue, x => x.CreatedTime <= dto.EndTime.Value);
// 如果需要按角色筛选
if (dto.RoleId.HasValue)
{
query = query.InnerJoin((u, ur) => u.Id == ur.UserId && ur.RoleId == dto.RoleId.Value);
}
var entityList = await query.ToPagedListAsync(dto);
// 转换并填充角色名称
var resultList = new List();
// 批量获取角色信息优化性能
var userIds = entityList.Rows.Select(x => x.Id).ToList();
var userRoles = await _userRoleRepository.AsQueryable()
.InnerJoin((ur, r) => ur.RoleId == r.Id)
.Where((ur, r) => userIds.Contains(ur.UserId))
.Select((ur, r) => new { ur.UserId,r.Id, RoleName = r.Name })
.ToListAsync();
foreach (var user in entityList.Rows)
{
var output = user.Adapt();
var roles = userRoles.Where(x => x.UserId == user.Id).Select(x => x.RoleName).ToList();
output.RoleNames = string.Join(",", roles);
var roleIds = userRoles.Where(x => x.UserId == user.Id).Select(x => x.Id).ToList();
output.RoleIds = string.Join(",", roleIds);
resultList.Add(output);
}
return new PageResult
{
PageNo = entityList.PageNo,
PageSize = entityList.PageSize,
Total = entityList.Total,
Rows = resultList,
Pages = entityList.Pages
};
}
///
/// 添加系统用户
///
///
///
[UnitOfWork, HttpPost("user")]
[DisplayName("添加系统用户")]
public async Task AddUser(AddSysUserInput dto)
{
// 校验账号是否已存在
if (await _repository.IsAnyAsync(x => x.Account == dto.Account))
throw new InvalidOperationException($"账号 {dto.Account} 已存在");
// 验证角色是否存在
if (dto.Roles != null && dto.Roles.Any())
{
var validRoleCount = await _roleRepository.AsQueryable()
.Where(x => dto.Roles.Contains(x.Id) && x.Status == AvailabilityStatus.Enable)
.CountAsync();
if (validRoleCount != dto.Roles.Count)
{
throw new InvalidOperationException("部分或全部角色不存在或已被禁用");
}
}
var user = dto.Adapt();
user.Id = _idGenerator.NextId();
string encode = _idGenerator.Encode(user.Id);
user.Password = MD5Encryption.Encrypt(encode + dto.Password);
user.CreatedTime = DateTime.Now; // 确保设置创建时间
// 处理角色关联
var roles = new List();
if (dto.Roles != null && dto.Roles.Any())
{
roles = dto.Roles.Select(x => new SysUserRole()
{
RoleId = x,
UserId = user.Id
}).ToList();
}
await _repository.InsertAsync(user);
if (roles.Any())
{
await _userRoleRepository.InsertRangeAsync(roles);
}
}
///
/// 更新系统用户信息
///
///
///
[DisplayName("更新系统用户信息")]
[UnitOfWork, HttpPut("user")]
public async Task UpdateUser(UpdateSysUserInput dto)
{
var user = await _repository.GetByIdAsync(dto.Id);
if (user == null) throw new InvalidOperationException("用户不存在");
// 校验账号是否重复(排除自己)
if (await _repository.IsAnyAsync(x => x.Account == dto.Account && x.Id != dto.Id))
throw new InvalidOperationException($"账号 {dto.Account} 已被使用");
// 验证角色是否存在
if (dto.Roles != null && dto.Roles.Any())
{
var validRoleCount = await _roleRepository.AsQueryable()
.Where(x => dto.Roles.Contains(x.Id) && x.Status == AvailabilityStatus.Enable)
.CountAsync();
if (validRoleCount != dto.Roles.Count)
{
throw new InvalidOperationException("部分或全部角色不存在或已被禁用");
}
}
// 先更新除密码外的其他字段
user.Name = dto.Name;
user.Account = dto.Account;
user.Status = dto.Status;
// 只有密码不为空时才更新密码
if (!string.IsNullOrWhiteSpace(dto.Password))
{
string encode = _idGenerator.Encode(user.Id);
user.Password = MD5Encryption.Encrypt(encode + dto.Password);
}
// 处理角色关联:先删后加
var roles = new List();
if (dto.Roles != null && dto.Roles.Any())
{
roles = dto.Roles.Select(x => new SysUserRole()
{
RoleId = x,
UserId = user.Id
}).ToList();
}
await _repository.UpdateAsync(user);
await _userRoleRepository.DeleteAsync(x => x.UserId == user.Id);
if (roles.Any())
{
await _userRoleRepository.InsertRangeAsync(roles);
}
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
}
///
/// 删除系统用户
///
///
///
[DisplayName("删除系统用户")]
[HttpDelete]
public override async Task Delete(KeyDto dto)
{
await base.Delete(dto);
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
}
[DisplayName("关联角色")]
[HttpPost("grantRole")]
public async Task GrantRole(GrantRoleInput input)
{
var user = await _repository.GetByIdAsync(input.UserId);
if (user == null) throw new InvalidOperationException("用户不存在");
var roles = input.RoleIds.Select(x => new SysUserRole()
{
RoleId = x,
UserId = input.UserId
}).ToList();
await _userRoleRepository.DeleteAsync(x => x.UserId == input.UserId);
if (roles.Any())
{
await _userRoleRepository.InsertRangeAsync(roles);
}
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
}
///
/// 系统用户详情
///
///
///
[DisplayName("系统用户详情")]
[HttpGet("detail")]
public async Task Detail([FromQuery] long id)
{
return await _repository.AsQueryable().Where(x => x.Id == id)
.Select(x => new UpdateSysUserInput()
{
Id = x.Id,
Name = x.Name,
Status = x.Status,
Account = x.Account,
Roles = SqlFunc.Subqueryable().Where(s => s.UserId == x.Id).ToList(s => s.RoleId)
}).FirstAsync();
}
///
/// 重置系统用户密码
///
///
[DisplayName("重置系统用户密码")]
[HttpPatch("reset")]
public async Task Reset(SysUserResetPasswordInput dto)
{
string encrypt = MD5Encryption.Encrypt(_idGenerator.Encode(dto.Id) + dto.Password);
await _repository.UpdateAsync(x => new SysUser()
{
Password = encrypt
}, x => x.Id == dto.Id);
}
///
/// 获取当前登录用户的信息
///
///
[DisplayName("获取登录用户的信息")]
[HttpGet("currentUserInfo")]
public async Task CurrentUserInfo()
{
var userId = _authManager.UserId;
return await _repository.AsQueryable().Where(x => x.Id == userId)
.Select(x => new SysUserInfoOutput
{
Name = x.Name,
Account = x.Account,
Avatar = x.Avatar,
Birthday = x.Birthday,
Email = x.Email,
Gender = x.Gender,
NickName = x.NickName,
Remark = x.Remark,
LastLoginIp = x.LastLoginIp,
LastLoginAddress = x.LastLoginAddress,
Mobile = x.Mobile,
OrgId = x.OrgId,
OrgName = SqlFunc.Subqueryable().Where(o => o.Id == x.OrgId).Select(o => o.Name)
})
.Mapper(dto =>
{
if (_authManager.IsSuperAdmin)
{
dto.AuthBtnList = _repository.AsSugarClient().Queryable()
.Where(x => x.Type == MenuType.Button || x.Type == MenuType.DataScope)
.Select(x => x.Code).ToList();
}
else
{
var list = _sysMenuService.GetAuthButtonCodeList(userId).GetAwaiter().GetResult();
dto.AuthBtnList = list.Where(x => x.Access).Select(x => x.Code).ToList();
}
})
.FirstAsync();
}
///
/// 用户修改账户密码
///
///
///
[DisplayName("用户修改账户密码")]
[HttpPatch("changePassword")]
public async Task ChangePassword(ChangePasswordOutput dto)
{
var userId = _authManager.UserId;
string encode = _idGenerator.Encode(userId);
string pwd = MD5Encryption.Encrypt($"{encode}{dto.OriginalPwd}");
if (!await _repository.IsAnyAsync(x => x.Id == userId && x.Password == pwd))
{
throw Oops.Bah("原密码错误");
}
pwd = MD5Encryption.Encrypt($"{encode}{dto.Password}");
await _repository.AsSugarClient().Updateable()
.SetColumns(x => new SysUser()
{
Password = pwd
})
.Where(x => x.Id == userId)
.ExecuteCommandHasChangeAsync();
}
///
/// 用户修改头像
///
///
///
[DisplayName("用户修改头像")]
[HttpPatch("uploadAvatar")]
public async Task UploadAvatar([FromBody] string url)
{
long userId = _authManager.UserId;
await _repository.UpdateAsync(x => new SysUser()
{
Avatar = url
}, x => x.Id == userId);
}
///
/// 系统用户修改自己的信息
///
///
[DisplayName("系统用户修改个人信息")]
[HttpPatch("updateCurrentUser")]
public async Task UpdateCurrentUser(UpdateCurrentUserInput dto)
{
long userId = _authManager.UserId;
await _repository.UpdateAsync(x => new SysUser()
{
Name = dto.Name,
Birthday = dto.Birthday,
Email = dto.Email,
Gender = dto.Gender,
Mobile = dto.Mobile,
NickName = dto.NickName
}, x => x.Id == userId);
}
}