using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; namespace Admin.NET.Plugin.ApprovalFlow.Service; /// /// 审批流审计服务 — 仅做请求审计日志,不用于核心审批推进 /// public class SysApprovalService : ITransient { private readonly SqlSugarRepository _approvalFlowRep; private readonly SqlSugarRepository _approvalFormRep; private readonly ApprovalFlowService _approvalFlowService; private static List? _cachedRoutes; private static DateTime _cacheTime = DateTime.MinValue; private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(5); public SysApprovalService( SqlSugarRepository approvalFlowRep, SqlSugarRepository approvalFormRep, ApprovalFlowService approvalFlowService) { _approvalFlowRep = approvalFlowRep; _approvalFormRep = approvalFormRep; _approvalFlowService = approvalFlowService; } /// /// 匹配审批流程(审计模式 — 仅记录,不阻断) /// [NonAction] public async Task MatchApproval(HttpContext context) { var path = context.Request.Path.ToString(); var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries); if (segments.Length < 3 || !segments[0].Equals("api", StringComparison.OrdinalIgnoreCase)) return; var funcName = segments[1]; var typeName = segments[2]; var routes = await GetCachedRoutes(); if (!routes.Any(r => { var parts = r.Split('/'); return parts.Length >= 2 && parts[0].Equals(funcName, StringComparison.OrdinalIgnoreCase) && parts[1].Equals(typeName, StringComparison.OrdinalIgnoreCase); })) return; var approvalFlow = new ApprovalFlowRecord { FormName = funcName, CreateTime = DateTime.Now, }; await _approvalFlowRep.InsertAsync(approvalFlow); var approvalForm = new ApprovalFormRecord { FlowId = approvalFlow.Id, FormName = funcName, FormType = typeName, CreateTime = DateTime.Now, }; await _approvalFormRep.InsertAsync(approvalForm); } /// /// 带缓存的路由列表,避免每个请求都查数据库 (B1 fix) /// private async Task> GetCachedRoutes() { if (_cachedRoutes != null && DateTime.Now - _cacheTime < CacheDuration) return _cachedRoutes; _cachedRoutes = await _approvalFlowService.FormRoutes(); _cacheTime = DateTime.Now; return _cachedRoutes; } /// /// 清除路由缓存(发布/更新流程时调用) /// [NonAction] public static void InvalidateRouteCache() { _cachedRoutes = null; } }