using YD_Event.Application.Auth; using YD_Event.Application.Menu; using YD_Event.Application.User.Dtos; using YD_Event.Core.Options; using YD_Event.Core.Shared; using Microsoft.Extensions.Options; 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; private readonly IOptionsMonitor _roleOptionsMonitor; public SysUserService(ISqlSugarRepository repository, ISqlSugarRepository userRoleRepository, ISqlSugarRepository roleRepository, ISqlSugarRepository orgRepository, SysMenuService sysMenuService, AuthManager authManager, IEasyCachingProvider easyCachingProvider, IIdGenerator idGenerator, IOptionsMonitor roleOptionsMonitor) : base(repository) { _repository = repository; _userRoleRepository = userRoleRepository; _roleRepository = roleRepository; _orgRepository = orgRepository; _sysMenuService = sysMenuService; _authManager = authManager; _easyCachingProvider = easyCachingProvider; _idGenerator = idGenerator; _roleOptionsMonitor = roleOptionsMonitor; } /// /// 检查当前登录用户是否是管理员 /// /// private async Task IsCurrentUserAdminAsync() { var userId = _authManager.UserId; // 首先检查是否是超级管理员(用户ID为1) if (_authManager.IsSuperAdmin) { return true; } // 检查用户是否拥有管理员角色 return await _userRoleRepository.IsAnyAsync(x => x.UserId == userId && x.RoleId == _roleOptionsMonitor.CurrentValue.AdminRoleId); } /// /// 系统用户分页查询 /// /// /// [DisplayName("系统用户分页查询")] [HttpGet("page")] public async Task> Page([FromQuery] QuerySysUserInput dto) { var isAdmin = await IsCurrentUserAdminAsync(); // 构造基本查询 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); } else if (!isAdmin) { // 非管理员用户,排除掉拥有管理员和单位用户角色的用户 var excludedRoleIds = new List { _roleOptionsMonitor.CurrentValue.AdminRoleId, _roleOptionsMonitor.CurrentValue.UnitUserRoleId }; // 使用子查询来获取那些拥有被排除角色的用户ID var excludedUserIds = await _userRoleRepository.AsQueryable() .Where(x => excludedRoleIds.Contains(x.RoleId)) .Select(x => x.UserId) .Distinct() .ToListAsync(); // 排除这些用户 query = query.Where(x => !excludedUserIds.Contains(x.Id)); } 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); } }