Merge branch 'dev' of https://gitea.nxsir.cn/nanxun/ql_apimanager_backend into dev
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using Apimanager_backend.Data;
|
||||
using Apimanager_backend.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public class ApiPackageItemService : IApiPackageItemService
|
||||
{
|
||||
private ApiContext _context;
|
||||
private ILogger<ApiPackageItemService> _logger;
|
||||
public ApiPackageItemService(ApiContext context,ILogger<ApiPackageItemService> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
public async Task<List<ApiPackageItem>> GetApiPackageItemsByApiIdAsync(int ApiId)
|
||||
{
|
||||
IQueryable<ApiPackageItem> query = _context.apiPackageItems.Include(x => x.ApiPackage).Where(x => x.ApiId == ApiId);
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,5 +116,16 @@ namespace Apimanager_backend.Services
|
||||
return await context.Apis.CountAsync();
|
||||
}
|
||||
#endregion
|
||||
#region 通过Api路径获取api信息
|
||||
public async Task<ApiInfoDto> GetApiInfoByEndpointAsync(string endpoint)
|
||||
{
|
||||
var apiInfo = await context.Apis.FirstOrDefaultAsync(x => x.Endpoint == endpoint);
|
||||
if (apiInfo == null)
|
||||
{
|
||||
throw new BaseException(3002, "API不存在");
|
||||
}
|
||||
return mapper.Map<ApiInfoDto>(apiInfo);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
using Apimanager_backend.Models;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public interface IApiPackageItemService
|
||||
{
|
||||
Task<List<ApiPackageItem>> GetApiPackageItemsByApiIdAsync(int ApiId);
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,12 @@ namespace Apimanager_backend.Services
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<int> ApiCountAsync();
|
||||
/// <summary>
|
||||
/// 通过api路径获取api信息
|
||||
/// </summary>
|
||||
/// <param name="endpoint">api路径</param>
|
||||
/// <returns></returns>
|
||||
public Task<ApiInfoDto> GetApiInfoByEndpointAsync(string endpoint);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using Apimanager_backend.Dtos;
|
||||
using Apimanager_backend.Models;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public interface IOrderService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取订单列表
|
||||
/// </summary>
|
||||
/// <param name="pageIndex">页索引</param>
|
||||
/// <param name="pageSize">页大小</param>
|
||||
/// <param name="desc">是否倒序</param>
|
||||
/// <returns></returns>
|
||||
Task<List<Order>> GetOrdersAsync(int pageIndex, int pageSize,bool desc,int? userId);
|
||||
/// <summary>
|
||||
/// 创建订单
|
||||
/// </summary>
|
||||
/// <param name="order">订单信息</param>
|
||||
/// <returns></returns>
|
||||
Task<Order> CreateOrderAsync(OrderDto order);
|
||||
Task<bool> UpdateOrderAsync(OrderDto order);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Apimanager_backend.Dtos;
|
||||
using Apimanager_backend.Models;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public interface IPayService
|
||||
{
|
||||
Task<PayReturnData> CreateEpay(Order order,PaymentConfig paymentConfig,string returnUrl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Apimanager_backend.Models;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public interface IPaymentConfigService
|
||||
{
|
||||
Task<PaymentConfig> GetPaymentConfigInfoByTypeAsync(string payType);
|
||||
Task<List<PaymentConfigDto>> GetAllPaymentAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Apimanager_backend.Models;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public interface IUserPackageService
|
||||
{
|
||||
Task<List<UserPackage>> GetUserPackagesByUserIdAsync(int userId);
|
||||
}
|
||||
}
|
||||
@@ -47,5 +47,18 @@ namespace Apimanager_backend.Services
|
||||
/// <param name="email">邮箱</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> IsEmailExist(string email);
|
||||
|
||||
/// <summary>
|
||||
/// 通过ApiToken获取用户
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<UserInfoDto?> GetByTokenAsync(string token);
|
||||
/// <summary>
|
||||
/// 更新用户头像
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> UpdateUserAvatarAsync(int userId,string url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
using Apimanager_backend.Data;
|
||||
using Apimanager_backend.Dtos;
|
||||
using Apimanager_backend.Exceptions;
|
||||
using Apimanager_backend.Models;
|
||||
using Apimanager_backend.Tools;
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public class OrderService:IOrderService
|
||||
{
|
||||
private ApiContext _apiContext;
|
||||
private IMapper mapper;
|
||||
private ILogger<OrderService> logger;
|
||||
public OrderService(ApiContext apiContext,IMapper mapper,ILogger<OrderService> logger)
|
||||
{
|
||||
_apiContext = apiContext;
|
||||
this.mapper = mapper;
|
||||
this.logger = logger;
|
||||
}
|
||||
#region 创建订单
|
||||
/// <summary>
|
||||
/// 创建订单
|
||||
/// </summary>
|
||||
/// <param name="order">订单信息</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public async Task<Order> CreateOrderAsync(OrderDto order)
|
||||
{
|
||||
var transaction = await _apiContext.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
Order orderInfo = mapper.Map<Order>(order);
|
||||
//初始化信息
|
||||
orderInfo.Status = OrderStatus.Pending;
|
||||
orderInfo.CreatedAt = DateTime.Now;
|
||||
orderInfo.OrderNumber = OrderNumberGenerator.Generate(order.UserId);
|
||||
_apiContext.Orders.Add(orderInfo);
|
||||
await _apiContext.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
return orderInfo;
|
||||
}catch(Exception e)
|
||||
{
|
||||
//异常回滚
|
||||
await transaction.RollbackAsync();
|
||||
logger.LogError(e.Message);
|
||||
throw new BaseException(4006,"支付系统错误");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region 获取订单列表
|
||||
/// <summary>
|
||||
/// 获取订单列表
|
||||
/// </summary>
|
||||
/// <param name="pageIndex">索引</param>
|
||||
/// <param name="pageSize">页大小</param>
|
||||
/// <param name="desc">是否倒序</param>
|
||||
/// <param name="userId">指定用户订单</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<Order>> GetOrdersAsync(int pageIndex, int pageSize, bool desc, int? userId)
|
||||
{
|
||||
IQueryable<Order> query = _apiContext.Orders.AsQueryable().OrderBy(x => x.Id);
|
||||
if(userId != null)
|
||||
{
|
||||
query.Where(x => x.UserId == userId);
|
||||
}
|
||||
//倒序
|
||||
if (desc)
|
||||
{
|
||||
query.OrderDescending();
|
||||
}
|
||||
//分页
|
||||
query = query.Skip((pageIndex - 1) * pageSize).Take(pageSize);
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 更新订单状态
|
||||
public async Task<bool> UpdateOrderAsync(OrderDto order)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _apiContext.Orders.SingleOrDefaultAsync(x => x.OrderNumber == order.OrderNumber || x.ThirdPartyOrderId == order.ThirdPartyOrderId);
|
||||
if (data == null)
|
||||
{
|
||||
throw new BaseException(4003, "订单未找到");
|
||||
}
|
||||
data.UpdatedAt = DateTime.Now;
|
||||
data.Status = order.Status;
|
||||
data.PaiAt = order.Status == OrderStatus.Completed ? DateTime.Now : null;
|
||||
_apiContext.Orders.Update(data);
|
||||
await _apiContext.SaveChangesAsync();
|
||||
return true;
|
||||
}catch(Exception e)
|
||||
{
|
||||
logger.LogError(e.Message);
|
||||
throw new BaseException(4003, "订单未找到");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using Apimanager_backend.Data;
|
||||
using Apimanager_backend.Dtos;
|
||||
using Apimanager_backend.Exceptions;
|
||||
using Apimanager_backend.Models;
|
||||
using Apimanager_backend.Tools;
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public class PayService : IPayService
|
||||
{
|
||||
private IMapper _mapper;
|
||||
private ILogger<PayService> _logger;
|
||||
private ApiContext _context;
|
||||
public PayService(IMapper mapper,ILogger<PayService> logger,ApiContext apiContext)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_logger = logger;
|
||||
_context = apiContext;
|
||||
}
|
||||
public async Task<PayReturnData> CreateEpay(Order order, PaymentConfig paymentConfig,string returnUrl)
|
||||
{
|
||||
try
|
||||
{
|
||||
var param = new Dictionary<string, string>();
|
||||
param["pid"] = paymentConfig.AppId;
|
||||
param["type"] = order.PaymentType.ToString().ToLower();
|
||||
param["out_trade_no"] = order.OrderNumber;
|
||||
param["notify_url"] = paymentConfig.NotifyUrl ?? "";
|
||||
param["return_url"] = returnUrl;
|
||||
param["name"] = "余额充值";
|
||||
param["money"] = order.Amount.ToString();
|
||||
param["clientip"] = "192.168.5.1";
|
||||
param["device"] = "pc";
|
||||
var res = await EpayHelper.ApiPayAsync(param, paymentConfig.SecretKey, paymentConfig.Url);
|
||||
order.ThirdPartyOrderId = res.trade_no;
|
||||
_context.Orders.Update(order);
|
||||
await _context.SaveChangesAsync();
|
||||
return _mapper.Map<PayReturnData>(res);
|
||||
}catch(Exception e)
|
||||
{
|
||||
_logger.LogError(e.Message);
|
||||
throw new BaseException(4001,"支付请求无效");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Apimanager_backend.Data;
|
||||
using Apimanager_backend.Exceptions;
|
||||
using Apimanager_backend.Models;
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public class PaymentConfigService : IPaymentConfigService
|
||||
{
|
||||
private ApiContext _context;
|
||||
private ILogger<PaymentConfigService> _logger;
|
||||
private IMapper _mapper;
|
||||
public PaymentConfigService(ApiContext context,ILogger<PaymentConfigService> logger,IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
}
|
||||
public async Task<List<PaymentConfigDto>> GetAllPaymentAsync()
|
||||
{
|
||||
var data = await _context.paymentConfigs.Where(x => x.IsEnabled).ToListAsync();
|
||||
return _mapper.Map<List<PaymentConfigDto>>(data);
|
||||
}
|
||||
|
||||
public async Task<PaymentConfig> GetPaymentConfigInfoByTypeAsync(string payType)
|
||||
{
|
||||
if(!Enum.TryParse(payType, true, out PaymentType parsedPayType))
|
||||
{
|
||||
throw new BaseException(4001, "未配置该支付方式的通道");
|
||||
}
|
||||
var data = await _context.paymentConfigs.SingleOrDefaultAsync(x => x.Method == parsedPayType);
|
||||
if(data == null)
|
||||
{
|
||||
throw new BaseException(4001, "未配置该支付方式的通道");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Apimanager_backend.Data;
|
||||
using Public;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
// PluginLoaderService.cs
|
||||
public class PluginLoaderService
|
||||
{
|
||||
private readonly IWebHostEnvironment _env;
|
||||
private readonly ILogger<PluginLoaderService> _logger;
|
||||
|
||||
public PluginLoaderService(
|
||||
IWebHostEnvironment env,
|
||||
ILogger<PluginLoaderService> logger)
|
||||
{
|
||||
_env = env;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void LoadPlugins(IServiceCollection services)
|
||||
{
|
||||
var pluginsDir = Path.Combine(_env.ContentRootPath, "ApiHandler");
|
||||
Directory.CreateDirectory(pluginsDir);
|
||||
|
||||
foreach (var dllPath in Directory.GetFiles(pluginsDir, "*.dll"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var assembly = LoadPluginAssembly(dllPath);
|
||||
RegisterPluginServices(assembly, services);
|
||||
_logger.LogInformation($"已加载插件: {Path.GetFileName(dllPath)}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"加载插件失败: {dllPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Assembly LoadPluginAssembly(string dllPath)
|
||||
{
|
||||
// 使用隔离的加载上下文
|
||||
var loadContext = new PluginLoadContext(dllPath);
|
||||
return loadContext.LoadFromAssemblyPath(dllPath);
|
||||
}
|
||||
|
||||
private void RegisterPluginServices(Assembly assembly, IServiceCollection services)
|
||||
{
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
if (typeof(IBillableApiHandler).IsAssignableFrom(type) &&
|
||||
!type.IsInterface &&
|
||||
!type.IsAbstract)
|
||||
{
|
||||
services.AddTransient(typeof(IBillableApiHandler), type);
|
||||
services.AddTransient(type); // 同时注册具体类型
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
using Apimanager_backend.Data;
|
||||
using Apimanager_backend.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Apimanager_backend.Services
|
||||
{
|
||||
public class UserPackageService : IUserPackageService
|
||||
{
|
||||
private ApiContext _context;
|
||||
public UserPackageService(ApiContext apiContext)
|
||||
{
|
||||
_context = apiContext;
|
||||
}
|
||||
public async Task<List<UserPackage>> GetUserPackagesByUserIdAsync(int userId)
|
||||
{
|
||||
IQueryable<UserPackage> query = _context.UserPackages.Include(x => x.Package).Where(x => x.UserId == userId);
|
||||
return await query.ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,5 +101,29 @@ namespace Apimanager_backend.Services
|
||||
await apiContext.SaveChangesAsync();
|
||||
return mapper.Map<UserInfoDto>(user);
|
||||
}
|
||||
|
||||
public async Task<UserInfoDto?> GetByTokenAsync(string token)
|
||||
{
|
||||
User? user = await apiContext.Users.Include(x => x.Roles).Include(x => x.Packages).SingleOrDefaultAsync(x => x.ApiKey == token);
|
||||
//未找到用户
|
||||
if (user == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return mapper.Map<UserInfoDto>(user);
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateUserAvatarAsync(int userId,string url)
|
||||
{
|
||||
var user = await apiContext.Users.FirstOrDefaultAsync(x => x.Id == userId);
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
user.Avatar = url;
|
||||
apiContext.Users.Update(user);
|
||||
await apiContext.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user