SysApprovalService.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.Extensions.Options;
  3. namespace Admin.NET.Plugin.ApprovalFlow.Service;
  4. /// <summary>
  5. /// 审批流审计服务 — 仅做请求审计日志,不用于核心审批推进
  6. /// </summary>
  7. public class SysApprovalService : ITransient
  8. {
  9. private readonly SqlSugarRepository<ApprovalFlowRecord> _approvalFlowRep;
  10. private readonly SqlSugarRepository<ApprovalFormRecord> _approvalFormRep;
  11. private readonly ApprovalFlowService _approvalFlowService;
  12. private static List<string>? _cachedRoutes;
  13. private static DateTime _cacheTime = DateTime.MinValue;
  14. private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(5);
  15. public SysApprovalService(
  16. SqlSugarRepository<ApprovalFlowRecord> approvalFlowRep,
  17. SqlSugarRepository<ApprovalFormRecord> approvalFormRep,
  18. ApprovalFlowService approvalFlowService)
  19. {
  20. _approvalFlowRep = approvalFlowRep;
  21. _approvalFormRep = approvalFormRep;
  22. _approvalFlowService = approvalFlowService;
  23. }
  24. /// <summary>
  25. /// 匹配审批流程(审计模式 — 仅记录,不阻断)
  26. /// </summary>
  27. [NonAction]
  28. public async Task MatchApproval(HttpContext context)
  29. {
  30. var path = context.Request.Path.ToString();
  31. var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
  32. if (segments.Length < 3 || !segments[0].Equals("api", StringComparison.OrdinalIgnoreCase))
  33. return;
  34. var funcName = segments[1];
  35. var typeName = segments[2];
  36. var routes = await GetCachedRoutes();
  37. if (!routes.Any(r =>
  38. {
  39. var parts = r.Split('/');
  40. return parts.Length >= 2
  41. && parts[0].Equals(funcName, StringComparison.OrdinalIgnoreCase)
  42. && parts[1].Equals(typeName, StringComparison.OrdinalIgnoreCase);
  43. }))
  44. return;
  45. var approvalFlow = new ApprovalFlowRecord
  46. {
  47. FormName = funcName,
  48. CreateTime = DateTime.Now,
  49. };
  50. await _approvalFlowRep.InsertAsync(approvalFlow);
  51. var approvalForm = new ApprovalFormRecord
  52. {
  53. FlowId = approvalFlow.Id,
  54. FormName = funcName,
  55. FormType = typeName,
  56. CreateTime = DateTime.Now,
  57. };
  58. await _approvalFormRep.InsertAsync(approvalForm);
  59. }
  60. /// <summary>
  61. /// 带缓存的路由列表,避免每个请求都查数据库 (B1 fix)
  62. /// </summary>
  63. private async Task<List<string>> GetCachedRoutes()
  64. {
  65. if (_cachedRoutes != null && DateTime.Now - _cacheTime < CacheDuration)
  66. return _cachedRoutes;
  67. _cachedRoutes = await _approvalFlowService.FormRoutes();
  68. _cacheTime = DateTime.Now;
  69. return _cachedRoutes;
  70. }
  71. /// <summary>
  72. /// 清除路由缓存(发布/更新流程时调用)
  73. /// </summary>
  74. [NonAction]
  75. public static void InvalidateRouteCache()
  76. {
  77. _cachedRoutes = null;
  78. }
  79. }