ql_apimanager_backend/Apimanager_backend/Tools/BillableApiDispatcher.cs

101 lines
3.5 KiB
C#

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<object> 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<UserPackage> userPackages = context.HttpContext.Items["userPackages"] as List<UserPackage>;
List<UserPackage> userPackageList = null;
if (userPackages == null || !(userPackages is IEnumerable<UserPackage>))
{
throw new BaseException(3004, "未购买该API套餐或权限不足");
}
userPackageList = ((IEnumerable<UserPackage>)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;
}
}
}