2026-03-17 15:32:01 +08:00

344 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/// <summary>
/// 系统用户管理
/// </summary>
public class SysUserService : BaseService<SysUser>, ITransient
{
private readonly ISqlSugarRepository<SysUser> _repository;
private readonly ISqlSugarRepository<SysUserRole> _userRoleRepository;
private readonly ISqlSugarRepository<SysRole> _roleRepository;
private readonly ISqlSugarRepository<SysOrganization> _orgRepository;
private readonly SysMenuService _sysMenuService;
private readonly AuthManager _authManager;
private readonly IEasyCachingProvider _easyCachingProvider;
private readonly IIdGenerator _idGenerator;
public SysUserService(ISqlSugarRepository<SysUser> repository,
ISqlSugarRepository<SysUserRole> userRoleRepository,
ISqlSugarRepository<SysRole> roleRepository,
ISqlSugarRepository<SysOrganization> 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;
}
/// <summary>
/// 系统用户分页查询
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[DisplayName("系统用户分页查询")]
[HttpGet("page")]
public async Task<PageResult<SysUserPageOutput>> 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<SysUserRole>((u, ur) => u.Id == ur.UserId && ur.RoleId == dto.RoleId.Value);
}
var entityList = await query.ToPagedListAsync(dto);
// 转换并填充角色名称
var resultList = new List<SysUserPageOutput>();
// 批量获取角色信息优化性能
var userIds = entityList.Rows.Select(x => x.Id).ToList();
var userRoles = await _userRoleRepository.AsQueryable()
.InnerJoin<SysRole>((ur, r) => ur.RoleId == r.Id)
.Where((ur, r) => userIds.Contains(ur.UserId))
.Select((ur, r) => new { ur.UserId, RoleName = r.Name })
.ToListAsync();
foreach (var user in entityList.Rows)
{
var output = user.Adapt<SysUserPageOutput>();
var roles = userRoles.Where(x => x.UserId == user.Id).Select(x => x.RoleName).ToList();
output.RoleNames = string.Join(",", roles);
resultList.Add(output);
}
return new PageResult<SysUserPageOutput>
{
PageNo = entityList.PageNo,
PageSize = entityList.PageSize,
Total = entityList.Total,
Rows = resultList,
Pages = entityList.Pages
};
}
/// <summary>
/// 添加系统用户
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[UnitOfWork, HttpPost]
[DisplayName("添加系统用户")]
public async Task AddUser(AddSysUserInput dto)
{
// 校验账号是否已存在
if (await _repository.IsAnyAsync(x => x.Account == dto.Account))
throw new InvalidOperationException($"账号 {dto.Account} 已存在");
var user = dto.Adapt<SysUser>();
user.Id = _idGenerator.NextId();
string encode = _idGenerator.Encode(user.Id);
user.Password = MD5Encryption.Encrypt(encode + "123456"); // 默认密码
user.CreatedTime = DateTime.Now; // 确保设置创建时间
// 处理角色关联
var roles = new List<SysUserRole>();
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);
}
}
/// <summary>
/// 更新系统用户信息
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[DisplayName("更新系统用户信息")]
[UnitOfWork, HttpPut]
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} 已被使用");
dto.Adapt(user);
// 处理角色关联:先删后加
var roles = new List<SysUserRole>();
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);
}
/// <summary>
/// 删除系统用户
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[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);
}
/// <summary>
/// 系统用户详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[DisplayName("系统用户详情")]
[HttpGet("detail")]
public async Task<UpdateSysUserInput> 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<SysUserRole>().Where(s => s.UserId == x.Id).ToList(s => s.RoleId)
}).FirstAsync();
}
/// <summary>
/// 重置系统用户密码
/// </summary>
/// <returns></returns>
[DisplayName("重置系统用户密码")]
[HttpPatch("reset")]
public async Task Reset(ResetPasswordInput dto)
{
string encrypt = MD5Encryption.Encrypt(_idGenerator.Encode(dto.Id) + dto.Password);
await _repository.UpdateAsync(x => new SysUser()
{
Password = encrypt
}, x => x.Id == dto.Id);
}
/// <summary>
/// 获取当前登录用户的信息
/// </summary>
/// <returns></returns>
[DisplayName("获取登录用户的信息")]
[HttpGet("currentUserInfo")]
public async Task<SysUserInfoOutput> 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<SysOrganization>().Where(o => o.Id == x.OrgId).Select(o => o.Name)
})
.Mapper(dto =>
{
if (_authManager.IsSuperAdmin)
{
dto.AuthBtnList = _repository.AsSugarClient().Queryable<SysMenu>()
.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();
}
/// <summary>
/// 用户修改账户密码
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[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<SysUser>()
.SetColumns(x => new SysUser()
{
Password = pwd
})
.Where(x => x.Id == userId)
.ExecuteCommandHasChangeAsync();
}
/// <summary>
/// 用户修改头像
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
[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);
}
/// <summary>
/// 系统用户修改自己的信息
/// </summary>
/// <returns></returns>
[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);
}
}