AdoS8ConfigActionPermissionController.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using Admin.NET.Plugin.AiDOP.Const.S8;
  2. using Admin.NET.Plugin.AiDOP.Infrastructure;
  3. using Admin.NET.Plugin.AiDOP.Infrastructure.S8;
  4. using Admin.NET.Plugin.AiDOP.Service.S8;
  5. using Microsoft.AspNetCore.Mvc;
  6. namespace Admin.NET.Plugin.AiDOP.Controllers.S8;
  7. /// <summary>
  8. /// S8-ACTION-PERMISSION-1:「异常操作权限」配置。
  9. ///
  10. /// <para>这是 <b>S8 全局</b>配置,<b>不属于某一条规则</b> —— 它回答的是
  11. /// 「哪些角色能对异常单做哪些动作」,与「这条规则由谁负责」(Rule Handler Pool)
  12. /// 是两个正交问题。刻意不放进规则弹窗:混在一起会让管理员以为改的是这条规则的权限,
  13. /// 实际改的是全租户。</para>
  14. /// </summary>
  15. [ApiController]
  16. [Route("api/aidop/s8/config/action-permissions")]
  17. [NonUnify]
  18. public class AdoS8ConfigActionPermissionController : ControllerBase
  19. {
  20. private readonly S8ExceptionActionRoleService _svc;
  21. private readonly S8TrustedScopeResolver _scope;
  22. private readonly IS8ExceptionActionAuthorizer _authorizer;
  23. public AdoS8ConfigActionPermissionController(
  24. S8ExceptionActionRoleService svc,
  25. S8TrustedScopeResolver scope,
  26. IS8ExceptionActionAuthorizer authorizer)
  27. {
  28. _svc = svc;
  29. _scope = scope;
  30. _authorizer = authorizer;
  31. }
  32. /// <summary>权限矩阵(目录内每个动作一行,未配置的也返回,前端要能显示"未配置")。</summary>
  33. [HttpGet]
  34. [S8Permission(S8PermissionCatalog.ConfigRead)]
  35. public async Task<IActionResult> MatrixAsync()
  36. {
  37. try { return Ok(await _svc.GetMatrixAsync(await _scope.ResolveAsync())); }
  38. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  39. }
  40. /// <summary>可授权角色(只列与 S8 相关的本租户角色,不机械返回全部)。</summary>
  41. [HttpGet("roles")]
  42. [S8Permission(S8PermissionCatalog.ConfigRead)]
  43. public async Task<IActionResult> RolesAsync()
  44. {
  45. try { return Ok(await _svc.GetAssignableRolesAsync(await _scope.ResolveAsync())); }
  46. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  47. }
  48. /// <summary>当前账号被允许的动作码 —— 前端据此控制按钮可见性,避免点了才 403。</summary>
  49. [HttpGet("mine")]
  50. [S8ExceptionAction(S8ExceptionActionCode.View)]
  51. [RequirePcMenuPath("/aidop/s8/exceptions")]
  52. public async Task<IActionResult> MineAsync()
  53. {
  54. try
  55. {
  56. var allowed = await _svc.GetMyAllowedActionsAsync(await _scope.ResolveAsync(), _authorizer);
  57. return Ok(allowed.ToList());
  58. }
  59. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  60. }
  61. /// <summary>覆盖某动作的授权角色(全量替换)。角色必须属于当前租户。</summary>
  62. [HttpPut("{actionCode}")]
  63. [S8Permission(S8PermissionCatalog.ConfigRoleWrite)]
  64. public async Task<IActionResult> SetAsync(string actionCode, [FromBody] AdoS8ActionRoleSetDto? body)
  65. {
  66. try
  67. {
  68. await _svc.SetActionRolesAsync(await _scope.ResolveAsync(), actionCode, body?.RoleIds);
  69. return Ok(new { actionCode, roleCount = body?.RoleIds?.Count ?? 0 });
  70. }
  71. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  72. }
  73. }
  74. public class AdoS8ActionRoleSetDto
  75. {
  76. /// <summary>该动作的完整授权角色集合。传空数组 = 关闭该动作(fail closed)。</summary>
  77. public List<long>? RoleIds { get; set; }
  78. }