using Apimanager_backend.Models; using System.Reflection; using System; using Apimanager_backend.Data; using Microsoft.EntityFrameworkCore; using Apimanager_backend.Exceptions; using Apimanager_backend.Dtos; using Public; using Apimanager_backend.Services; namespace Apimanager_backend.Tools { public class BillableApiDispatcher { private readonly IServiceProvider _serviceProvider; private readonly ApiContext _db; private PluginLoaderService _pluginLoaderService; public BillableApiDispatcher(IServiceProvider sp, ApiContext db,PluginLoaderService pluginLoaderService) { _serviceProvider = sp; _db = db; _pluginLoaderService = pluginLoaderService; } public async Task DispatchAsync(string webPath,int apiId,string code, ApiCallContext context) { //_pluginLoaderService.LoadPlugins(new ServiceCollection()); // 1. 安全验证 string dllPath = webPath + "\\ApiHandler\\" + code + ".dll"; if (!System.IO.File.Exists(dllPath)) throw new BaseException(3002, "接口实现未找到"); // 2. 加载程序集 var assembly = Assembly.LoadFrom(dllPath); // 或使用 AssemblyLoadContext.Default.LoadFromAssemblyPath // 3. 查找实现类 var type = assembly.GetTypes() .FirstOrDefault(t => typeof(IBillableApiHandler).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract && t.Name.Equals(code, StringComparison.OrdinalIgnoreCase)); if (type == null) throw new BaseException(3002,"接口实现未找到"); List userPackages = context.HttpContext.Items["userPackages"] as List; List userPackageList = null; if (userPackages == null || !(userPackages is IEnumerable)) { throw new BaseException(3004, "未购买该API套餐或权限不足"); } userPackageList = ((IEnumerable)userPackages).ToList(); userPackageList = userPackageList.Where(x => x.ExpiryDate > DateTime.Now).ToList(); if (userPackageList.Count == 0) { throw new BaseException(3004, "未购买该API套餐或权限不足"); } var maxCountUserPackage = userPackageList.MaxBy(x => x.RemainingCalls); if (maxCountUserPackage.RemainingCalls <= 0) { throw new BaseException(3004, "套餐可用额度不足"); } var uPackage = await _db.UserPackages.SingleOrDefaultAsync(x => x.Id == maxCountUserPackage.Id); if (uPackage == null) { throw new BaseException(3004, "未购买该API套餐或权限不足"); } uPackage.RemainingCalls -= 1; _db.UserPackages.Update(uPackage); var handler = (IBillableApiHandler)Activator.CreateInstance(type)!; // 执行接口 var result = await handler.ExecuteAsync(context); // 记录调用日志 _db.CallLogs.Add(new ApiCallLog { ApiId = apiId, UserId = context.UserId, CallTime = DateTime.UtcNow }); await _db.SaveChangesAsync(); return result; } } }