2026-05-14 15:27:16 +08:00
|
|
|
|
using YD_Event.Application.Auth;
|
2026-04-12 16:54:39 +08:00
|
|
|
|
using YD_Event.Application.Role.Dtos;
|
2026-05-14 15:27:16 +08:00
|
|
|
|
using YD_Event.Core.Options;
|
2026-02-08 15:57:40 +08:00
|
|
|
|
using YD_Event.Core.Shared;
|
2026-05-14 15:27:16 +08:00
|
|
|
|
using Microsoft.Extensions.Options;
|
2025-12-17 10:32:52 +08:00
|
|
|
|
|
2025-12-17 11:12:13 +08:00
|
|
|
|
namespace YD_Event.Application.Role;
|
2025-12-17 10:32:52 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 角色管理
|
|
|
|
|
|
/// </summary>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
public class SysRoleService : BaseService<SysRole>, ITransient
|
2025-12-17 10:32:52 +08:00
|
|
|
|
{
|
|
|
|
|
|
private readonly ISqlSugarRepository<SysRole> _sysRoleRepository;
|
|
|
|
|
|
private readonly ISqlSugarRepository<SysRoleMenu> _sysRoleMenuRepository;
|
2026-05-14 15:27:16 +08:00
|
|
|
|
private readonly ISqlSugarRepository<SysUserRole> _sysUserRoleRepository;
|
2025-12-17 10:32:52 +08:00
|
|
|
|
private readonly IEasyCachingProvider _easyCachingProvider;
|
|
|
|
|
|
private readonly IIdGenerator _idGenerator;
|
2026-05-14 15:27:16 +08:00
|
|
|
|
private readonly AuthManager _authManager;
|
|
|
|
|
|
private readonly IOptionsMonitor<RoleOptions> _roleOptionsMonitor;
|
2025-12-17 10:32:52 +08:00
|
|
|
|
|
|
|
|
|
|
public SysRoleService(ISqlSugarRepository<SysRole> sysRoleRepository,
|
|
|
|
|
|
ISqlSugarRepository<SysRoleMenu> sysRoleMenuRepository,
|
2026-05-14 15:27:16 +08:00
|
|
|
|
ISqlSugarRepository<SysUserRole> sysUserRoleRepository,
|
2025-12-17 10:32:52 +08:00
|
|
|
|
IEasyCachingProvider easyCachingProvider,
|
2026-05-14 15:27:16 +08:00
|
|
|
|
IIdGenerator idGenerator,
|
|
|
|
|
|
AuthManager authManager,
|
|
|
|
|
|
IOptionsMonitor<RoleOptions> roleOptionsMonitor) : base(sysRoleRepository)
|
2025-12-17 10:32:52 +08:00
|
|
|
|
{
|
|
|
|
|
|
_sysRoleRepository = sysRoleRepository;
|
|
|
|
|
|
_sysRoleMenuRepository = sysRoleMenuRepository;
|
2026-05-14 15:27:16 +08:00
|
|
|
|
_sysUserRoleRepository = sysUserRoleRepository;
|
2025-12-17 10:32:52 +08:00
|
|
|
|
_easyCachingProvider = easyCachingProvider;
|
|
|
|
|
|
_idGenerator = idGenerator;
|
2026-05-14 15:27:16 +08:00
|
|
|
|
_authManager = authManager;
|
|
|
|
|
|
_roleOptionsMonitor = roleOptionsMonitor;
|
2025-12-17 10:32:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 角色分页查询
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("角色分页查询")]
|
|
|
|
|
|
[HttpGet("page")]
|
2025-12-17 10:32:52 +08:00
|
|
|
|
public async Task<PageResult<SysRolePageOutput>> Page([FromQuery] SysRoleQueryInput dto)
|
|
|
|
|
|
{
|
2026-05-14 15:27:16 +08:00
|
|
|
|
var isAdmin = await IsCurrentUserAdminAsync();
|
|
|
|
|
|
var query = _sysRoleRepository.AsQueryable()
|
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(dto.Name), x => x.Name.Contains(dto.Name));
|
|
|
|
|
|
|
|
|
|
|
|
if (!isAdmin)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 非管理员用户,过滤掉管理员和单位用户角色
|
|
|
|
|
|
query = query.Where(x => x.Id != _roleOptionsMonitor.CurrentValue.AdminRoleId && x.Id != _roleOptionsMonitor.CurrentValue.UnitUserRoleId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return await query
|
2025-12-17 10:32:52 +08:00
|
|
|
|
.OrderBy(x => x.Sort)
|
|
|
|
|
|
.OrderByDescending(x => x.Id)
|
|
|
|
|
|
.Select(x => new SysRolePageOutput
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = x.Id,
|
|
|
|
|
|
Name = x.Name,
|
|
|
|
|
|
CreatedTime = x.CreatedTime,
|
|
|
|
|
|
Status = x.Status,
|
|
|
|
|
|
Code = x.Code,
|
|
|
|
|
|
Sort = x.Sort,
|
|
|
|
|
|
Remark = x.Remark
|
|
|
|
|
|
}).ToPagedListAsync(dto);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-14 15:27:16 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 检查当前登录用户是否是管理员
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private async Task<bool> IsCurrentUserAdminAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = _authManager.UserId;
|
|
|
|
|
|
// 首先检查是否是超级管理员(用户ID为1000)
|
|
|
|
|
|
if (_authManager.IsSuperAdmin)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 检查用户是否拥有管理员角色
|
|
|
|
|
|
return await _sysUserRoleRepository.IsAnyAsync(x => x.UserId == userId && x.RoleId == _roleOptionsMonitor.CurrentValue.AdminRoleId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-17 10:32:52 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 添加角色
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("添加角色")]
|
2025-12-17 10:32:52 +08:00
|
|
|
|
[HttpPost("add")]
|
|
|
|
|
|
[UnitOfWork]
|
|
|
|
|
|
public async Task AddRole(AddSysRoleInput dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
var role = dto.Adapt<SysRole>();
|
|
|
|
|
|
role.Id = _idGenerator.NewLong();
|
2026-02-08 15:57:40 +08:00
|
|
|
|
// 自动生成Code,避免重复
|
|
|
|
|
|
role.Code = $"Role_{role.Id}";
|
|
|
|
|
|
|
|
|
|
|
|
if (await _sysRoleRepository.IsAnyAsync(x => x.Name == dto.Name))
|
2025-12-17 10:32:52 +08:00
|
|
|
|
{
|
2026-02-08 15:57:40 +08:00
|
|
|
|
throw new InvalidOperationException($"角色名称 {dto.Name} 已存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-17 10:32:52 +08:00
|
|
|
|
await _sysRoleRepository.InsertAsync(role);
|
2026-04-12 16:54:39 +08:00
|
|
|
|
|
|
|
|
|
|
// 保存角色权限
|
|
|
|
|
|
var menuIds = dto.MenuIds ?? dto.Menus;
|
|
|
|
|
|
if (menuIds != null && menuIds.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
var roleMenus = menuIds.Select(x => new SysRoleMenu()
|
|
|
|
|
|
{
|
|
|
|
|
|
MenuId = x,
|
|
|
|
|
|
RoleId = role.Id
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
await _sysRoleMenuRepository.InsertRangeAsync(roleMenus);
|
|
|
|
|
|
}
|
2025-12-17 10:32:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 更新角色
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("更新角色")]
|
2025-12-17 10:32:52 +08:00
|
|
|
|
[HttpPut("edit")]
|
|
|
|
|
|
[UnitOfWork]
|
|
|
|
|
|
public async Task UpdateRole(UpdateSysRoleInput dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sysRole = await _sysRoleRepository.GetByIdAsync(dto.Id);
|
|
|
|
|
|
if (sysRole == null)
|
|
|
|
|
|
{
|
2026-02-08 15:57:40 +08:00
|
|
|
|
throw new InvalidOperationException("角色不存在");
|
2025-12-17 10:32:52 +08:00
|
|
|
|
}
|
2026-02-08 15:57:40 +08:00
|
|
|
|
|
|
|
|
|
|
if (await _sysRoleRepository.IsAnyAsync(x => x.Id != dto.Id && x.Name == dto.Name))
|
2025-12-17 10:32:52 +08:00
|
|
|
|
{
|
2026-02-08 15:57:40 +08:00
|
|
|
|
throw new InvalidOperationException($"角色名称 {dto.Name} 已存在");
|
2025-12-17 10:32:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dto.Adapt(sysRole);
|
2026-02-08 15:57:40 +08:00
|
|
|
|
await _sysRoleRepository.UpdateAsync(sysRole);
|
2026-04-12 16:54:39 +08:00
|
|
|
|
|
2026-06-06 23:34:12 +08:00
|
|
|
|
// 更新角色权限 - 软删旧权限
|
|
|
|
|
|
await _sysRoleMenuRepository.SoftDeleteAsync(x => x.RoleId == dto.Id);
|
2026-04-12 16:54:39 +08:00
|
|
|
|
var menuIds = dto.MenuIds ?? dto.Menus;
|
|
|
|
|
|
if (menuIds != null && menuIds.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
var roleMenus = menuIds.Select(x => new SysRoleMenu()
|
|
|
|
|
|
{
|
|
|
|
|
|
MenuId = x,
|
|
|
|
|
|
RoleId = dto.Id
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
await _sysRoleMenuRepository.InsertRangeAsync(roleMenus);
|
|
|
|
|
|
}
|
|
|
|
|
|
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
|
2026-02-08 15:57:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 授权角色权限
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[DisplayName("授权角色权限")]
|
|
|
|
|
|
[HttpPost("grantPermission")]
|
|
|
|
|
|
[UnitOfWork]
|
|
|
|
|
|
public async Task GrantPermission(GrantRolePermissionInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sysRole = await _sysRoleRepository.GetByIdAsync(input.Id);
|
|
|
|
|
|
if (sysRole == null) throw new InvalidOperationException("角色不存在");
|
|
|
|
|
|
|
|
|
|
|
|
var roleMenus = input.MenuIds.Select(x => new SysRoleMenu()
|
2025-12-17 10:32:52 +08:00
|
|
|
|
{
|
|
|
|
|
|
MenuId = x,
|
2026-02-08 15:57:40 +08:00
|
|
|
|
RoleId = input.Id
|
2025-12-17 10:32:52 +08:00
|
|
|
|
}).ToList();
|
2026-02-08 15:57:40 +08:00
|
|
|
|
|
2026-06-06 23:34:12 +08:00
|
|
|
|
await _sysRoleMenuRepository.SoftDeleteAsync(x => x.RoleId == input.Id);
|
2026-02-08 15:57:40 +08:00
|
|
|
|
if (roleMenus.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
await _sysRoleMenuRepository.InsertRangeAsync(roleMenus);
|
|
|
|
|
|
}
|
2025-12-17 10:32:52 +08:00
|
|
|
|
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取角色可访问的菜单和按钮id
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">角色id</param>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("获取角色可访问的菜单和按钮id")]
|
|
|
|
|
|
[HttpGet("getRoleMenu")]
|
|
|
|
|
|
public async Task<List<long>> GetRoleMenu([FromQuery] long id)
|
2025-12-17 10:32:52 +08:00
|
|
|
|
{
|
2026-02-08 15:57:40 +08:00
|
|
|
|
return await _sysRoleRepository.AsQueryable()
|
|
|
|
|
|
.InnerJoin<SysRoleMenu>((role, roleMenu) => role.Id == roleMenu.RoleId)
|
2025-12-17 10:32:52 +08:00
|
|
|
|
.InnerJoin<SysMenu>((role, roleMenu, menu) => roleMenu.MenuId == menu.Id)
|
|
|
|
|
|
.Where((role, roleMenu, menu) => role.Id == id && menu.Status == AvailabilityStatus.Enable)
|
2026-02-08 15:57:40 +08:00
|
|
|
|
.Select((role, roleMenu) => roleMenu.MenuId)
|
|
|
|
|
|
.ToListAsync();
|
2025-12-17 10:32:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 修改角色状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("修改角色状态")]
|
|
|
|
|
|
[HttpPut("setStatus")]
|
2025-12-17 10:32:52 +08:00
|
|
|
|
public override async Task SetStatus(AvailabilityDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
await base.SetStatus(dto);
|
|
|
|
|
|
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 删除角色
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("删除角色")]
|
|
|
|
|
|
[HttpDelete("delete")]
|
2025-12-17 10:32:52 +08:00
|
|
|
|
public override async Task Delete(KeyDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
await base.Delete(dto);
|
2026-06-06 23:34:12 +08:00
|
|
|
|
// 软删关联权限
|
|
|
|
|
|
await _sysRoleMenuRepository.SoftDeleteAsync(x => x.RoleId == dto.Id);
|
2025-12-17 10:32:52 +08:00
|
|
|
|
await _easyCachingProvider.RemoveByPrefixAsync(CacheConst.PermissionKey);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 角色下拉选项
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2026-02-08 15:57:40 +08:00
|
|
|
|
[DisplayName("角色下拉选项")]
|
|
|
|
|
|
[HttpGet("select")]
|
2025-12-17 10:32:52 +08:00
|
|
|
|
public async Task<List<SelectOutput>> RoleSelect()
|
|
|
|
|
|
{
|
2026-05-14 15:27:16 +08:00
|
|
|
|
var isAdmin = await IsCurrentUserAdminAsync();
|
|
|
|
|
|
var query = _sysRoleRepository.AsQueryable().Where(x => x.Status == AvailabilityStatus.Enable);
|
|
|
|
|
|
|
|
|
|
|
|
if (!isAdmin)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 非管理员用户,过滤掉管理员和单位用户角色
|
|
|
|
|
|
query = query.Where(x => x.Id != _roleOptionsMonitor.CurrentValue.AdminRoleId && x.Id != _roleOptionsMonitor.CurrentValue.UnitUserRoleId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return await query
|
2025-12-17 10:32:52 +08:00
|
|
|
|
.OrderBy(x => x.Sort)
|
|
|
|
|
|
.OrderBy(x => x.Id)
|
|
|
|
|
|
.Select(x => new SelectOutput()
|
|
|
|
|
|
{
|
|
|
|
|
|
Value = x.Id,
|
|
|
|
|
|
Label = x.Name
|
|
|
|
|
|
}).ToListAsync();
|
|
|
|
|
|
}
|
2026-04-12 16:54:39 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 角色下拉选项(兼容接口)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[DisplayName("角色下拉选项(兼容接口)")]
|
|
|
|
|
|
[HttpGet("roleselect")]
|
|
|
|
|
|
public async Task<List<SelectOutput>> RoleSelectCompat()
|
|
|
|
|
|
{
|
|
|
|
|
|
return await RoleSelect();
|
|
|
|
|
|
}
|
2026-02-08 15:57:40 +08:00
|
|
|
|
}
|